golf-mcp 0.1.20__py3-none-any.whl → 0.2.1__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.

Potentially problematic release.


This version of golf-mcp might be problematic. Click here for more details.

Files changed (123) hide show
  1. golf/__init__.py +9 -1
  2. golf/_endpoints.py +6 -0
  3. golf/_endpoints_fallback.py +10 -0
  4. golf/auth/__init__.py +235 -83
  5. golf/auth/api_key.py +6 -14
  6. golf/auth/factory.py +358 -0
  7. golf/auth/helpers.py +12 -42
  8. golf/auth/providers.py +446 -0
  9. golf/auth/registry.py +256 -0
  10. golf/cli/branding.py +192 -0
  11. golf/cli/main.py +28 -69
  12. golf/commands/__init__.py +2 -0
  13. golf/commands/build.py +4 -7
  14. golf/commands/init.py +30 -53
  15. golf/commands/run.py +50 -20
  16. golf/core/builder.py +355 -414
  17. golf/core/builder_auth.py +63 -144
  18. golf/core/builder_telemetry.py +26 -3
  19. golf/core/config.py +38 -59
  20. golf/core/parser.py +132 -139
  21. golf/core/platform.py +12 -10
  22. golf/core/telemetry.py +11 -19
  23. golf/core/transformer.py +38 -15
  24. golf/examples/__pycache__/__init__.cpython-311.pyc +0 -0
  25. golf/examples/basic/.coverage +0 -0
  26. golf/examples/basic/.env.example +8 -4
  27. golf/examples/basic/README.md +117 -45
  28. golf/examples/basic/__pycache__/auth.cpython-311.pyc +0 -0
  29. golf/examples/basic/auth.py +76 -0
  30. golf/examples/basic/golf.json +2 -5
  31. golf/examples/basic/htmlcov/.gitignore +2 -0
  32. golf/examples/basic/htmlcov/class_index.html +547 -0
  33. golf/examples/basic/htmlcov/coverage_html_cb_6fb7b396.js +733 -0
  34. golf/examples/basic/htmlcov/favicon_32_cb_58284776.png +0 -0
  35. golf/examples/basic/htmlcov/function_index.html +2091 -0
  36. golf/examples/basic/htmlcov/index.html +349 -0
  37. golf/examples/basic/htmlcov/keybd_closed_cb_ce680311.png +0 -0
  38. golf/examples/basic/htmlcov/status.json +1 -0
  39. golf/examples/basic/htmlcov/style_cb_8e611ae1.css +337 -0
  40. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496___init___py.html +323 -0
  41. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_api_key_py.html +170 -0
  42. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_factory_py.html +430 -0
  43. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_helpers_py.html +288 -0
  44. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_providers_py.html +493 -0
  45. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_registry_py.html +353 -0
  46. golf/examples/basic/htmlcov/z_3ec3b3f490dc0950___init___py.html +120 -0
  47. golf/examples/basic/htmlcov/z_3ec3b3f490dc0950_instrumentation_py.html +1535 -0
  48. golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db___init___py.html +98 -0
  49. golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_branding_py.html +289 -0
  50. golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_main_py.html +476 -0
  51. golf/examples/basic/htmlcov/z_5a6c4e6bcc86fb2f___init___py.html +97 -0
  52. golf/examples/basic/htmlcov/z_6cadab9ec0df475d___init___py.html +102 -0
  53. golf/examples/basic/htmlcov/z_6cadab9ec0df475d_build_py.html +178 -0
  54. golf/examples/basic/htmlcov/z_6cadab9ec0df475d_init_py.html +387 -0
  55. golf/examples/basic/htmlcov/z_6cadab9ec0df475d_run_py.html +222 -0
  56. golf/examples/basic/htmlcov/z_6fcdee0582ba84e4___init___py.html +106 -0
  57. golf/examples/basic/htmlcov/z_6fcdee0582ba84e4__endpoints_fallback_py.html +107 -0
  58. golf/examples/basic/htmlcov/z_7ba499ed22986217___init___py.html +98 -0
  59. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_auth_py.html +306 -0
  60. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_metrics_py.html +329 -0
  61. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_py.html +1471 -0
  62. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_telemetry_py.html +186 -0
  63. golf/examples/basic/htmlcov/z_7ba499ed22986217_config_py.html +315 -0
  64. golf/examples/basic/htmlcov/z_7ba499ed22986217_parser_py.html +1149 -0
  65. golf/examples/basic/htmlcov/z_7ba499ed22986217_platform_py.html +279 -0
  66. golf/examples/basic/htmlcov/z_7ba499ed22986217_telemetry_py.html +589 -0
  67. golf/examples/basic/htmlcov/z_7ba499ed22986217_transformer_py.html +286 -0
  68. golf/examples/basic/htmlcov/z_7d7da37693a43688___init___py.html +107 -0
  69. golf/examples/basic/htmlcov/z_7d7da37693a43688_collector_py.html +417 -0
  70. golf/examples/basic/htmlcov/z_7d7da37693a43688_registry_py.html +109 -0
  71. golf/examples/basic/htmlcov/z_abe733142b40ad4e___init___py.html +109 -0
  72. golf/examples/basic/htmlcov/z_abe733142b40ad4e_context_py.html +150 -0
  73. golf/examples/basic/htmlcov/z_abe733142b40ad4e_elicitation_py.html +267 -0
  74. golf/examples/basic/htmlcov/z_abe733142b40ad4e_sampling_py.html +318 -0
  75. golf/examples/basic/prompts/__pycache__/welcome.cpython-311.pyc +0 -0
  76. golf/examples/basic/prompts/welcome.py +3 -5
  77. golf/examples/basic/resources/__pycache__/current_time.cpython-311.pyc +0 -0
  78. golf/examples/basic/resources/__pycache__/info.cpython-311.pyc +0 -0
  79. golf/examples/basic/resources/current_time.py +5 -13
  80. golf/examples/basic/resources/weather/__pycache__/common.cpython-311.pyc +0 -0
  81. golf/examples/basic/resources/weather/__pycache__/current.cpython-311.pyc +0 -0
  82. golf/examples/basic/resources/weather/__pycache__/forecast.cpython-311.pyc +0 -0
  83. golf/examples/basic/resources/weather/city.py +46 -0
  84. golf/examples/basic/resources/weather/common.py +4 -11
  85. golf/examples/basic/resources/weather/current.py +5 -5
  86. golf/examples/basic/resources/weather/forecast.py +5 -5
  87. golf/examples/basic/tools/__pycache__/calculator.cpython-311.pyc +0 -0
  88. golf/examples/basic/tools/calculator.py +94 -0
  89. golf/examples/basic/tools/say/__pycache__/hello.cpython-311.pyc +0 -0
  90. golf/examples/basic/tools/say/hello.py +65 -0
  91. golf/metrics/collector.py +100 -19
  92. golf/telemetry/__init__.py +4 -0
  93. golf/telemetry/instrumentation.py +484 -178
  94. golf/utilities/__init__.py +12 -0
  95. golf/utilities/context.py +53 -0
  96. golf/utilities/elicitation.py +170 -0
  97. golf/utilities/sampling.py +221 -0
  98. {golf_mcp-0.1.20.dist-info → golf_mcp-0.2.1.dist-info}/METADATA +51 -104
  99. golf_mcp-0.2.1.dist-info/RECORD +110 -0
  100. golf/auth/oauth.py +0 -861
  101. golf/auth/provider.py +0 -115
  102. golf/examples/api_key/.env +0 -2
  103. golf/examples/api_key/.env.example +0 -1
  104. golf/examples/api_key/README.md +0 -84
  105. golf/examples/api_key/golf.json +0 -8
  106. golf/examples/api_key/pre_build.py +0 -11
  107. golf/examples/api_key/tools/issues/create.py +0 -93
  108. golf/examples/api_key/tools/issues/list.py +0 -92
  109. golf/examples/api_key/tools/repos/list.py +0 -111
  110. golf/examples/api_key/tools/search/code.py +0 -106
  111. golf/examples/api_key/tools/users/get.py +0 -82
  112. golf/examples/basic/.env +0 -5
  113. golf/examples/basic/pre_build.py +0 -28
  114. golf/examples/basic/tools/github_user.py +0 -65
  115. golf/examples/basic/tools/hello.py +0 -34
  116. golf/examples/basic/tools/payments/charge.py +0 -70
  117. golf/examples/basic/tools/payments/common.py +0 -36
  118. golf/examples/basic/tools/payments/refund.py +0 -61
  119. golf_mcp-0.1.20.dist-info/RECORD +0 -60
  120. {golf_mcp-0.1.20.dist-info → golf_mcp-0.2.1.dist-info}/WHEEL +0 -0
  121. {golf_mcp-0.1.20.dist-info → golf_mcp-0.2.1.dist-info}/entry_points.txt +0 -0
  122. {golf_mcp-0.1.20.dist-info → golf_mcp-0.2.1.dist-info}/licenses/LICENSE +0 -0
  123. {golf_mcp-0.1.20.dist-info → golf_mcp-0.2.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1535 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+ <title>Coverage for /Users/antonigmitruk/golf/src/golf/telemetry/instrumentation.py: 0%</title>
6
+ <link rel="icon" sizes="32x32" href="favicon_32_cb_58284776.png">
7
+ <link rel="stylesheet" href="style_cb_8e611ae1.css" type="text/css">
8
+ <script src="coverage_html_cb_6fb7b396.js" defer></script>
9
+ </head>
10
+ <body class="pyfile">
11
+ <header>
12
+ <div class="content">
13
+ <h1>
14
+ <span class="text">Coverage for </span><b>/Users/antonigmitruk/golf/src/golf/telemetry/instrumentation.py</b>:
15
+ <span class="pc_cov">0%</span>
16
+ </h1>
17
+ <aside id="help_panel_wrapper">
18
+ <input id="help_panel_state" type="checkbox">
19
+ <label for="help_panel_state">
20
+ <img id="keyboard_icon" src="keybd_closed_cb_ce680311.png" alt="Show/hide keyboard shortcuts">
21
+ </label>
22
+ <div id="help_panel">
23
+ <p class="legend">Shortcuts on this page</p>
24
+ <div class="keyhelp">
25
+ <p>
26
+ <kbd>r</kbd>
27
+ <kbd>m</kbd>
28
+ <kbd>x</kbd>
29
+ &nbsp; toggle line displays
30
+ </p>
31
+ <p>
32
+ <kbd>j</kbd>
33
+ <kbd>k</kbd>
34
+ &nbsp; next/prev highlighted chunk
35
+ </p>
36
+ <p>
37
+ <kbd>0</kbd> &nbsp; (zero) top of page
38
+ </p>
39
+ <p>
40
+ <kbd>1</kbd> &nbsp; (one) first highlighted chunk
41
+ </p>
42
+ <p>
43
+ <kbd>[</kbd>
44
+ <kbd>]</kbd>
45
+ &nbsp; prev/next file
46
+ </p>
47
+ <p>
48
+ <kbd>u</kbd> &nbsp; up to the index
49
+ </p>
50
+ <p>
51
+ <kbd>?</kbd> &nbsp; show/hide this help
52
+ </p>
53
+ </div>
54
+ </div>
55
+ </aside>
56
+ <h2>
57
+ <span class="text">779 statements &nbsp;</span>
58
+ <button type="button" class="run button_toggle_run" value="run" data-shortcut="r" title="Toggle lines run">0<span class="text"> run</span></button>
59
+ <button type="button" class="mis show_mis button_toggle_mis" value="mis" data-shortcut="m" title="Toggle lines missing">779<span class="text"> missing</span></button>
60
+ <button type="button" class="exc show_exc button_toggle_exc" value="exc" data-shortcut="x" title="Toggle lines excluded">0<span class="text"> excluded</span></button>
61
+ </h2>
62
+ <p class="text">
63
+ <a id="prevFileLink" class="nav" href="z_3ec3b3f490dc0950___init___py.html">&#xab; prev</a> &nbsp; &nbsp;
64
+ <a id="indexLink" class="nav" href="index.html">&Hat; index</a> &nbsp; &nbsp;
65
+ <a id="nextFileLink" class="nav" href="z_abe733142b40ad4e___init___py.html">&#xbb; next</a>
66
+ &nbsp; &nbsp; &nbsp;
67
+ <a class="nav" href="https://coverage.readthedocs.io/en/7.6.12">coverage.py v7.6.12</a>,
68
+ created at 2025-08-16 18:46 +0200
69
+ </p>
70
+ <aside class="hidden">
71
+ <button type="button" class="button_next_chunk" data-shortcut="j"></button>
72
+ <button type="button" class="button_prev_chunk" data-shortcut="k"></button>
73
+ <button type="button" class="button_top_of_page" data-shortcut="0"></button>
74
+ <button type="button" class="button_first_chunk" data-shortcut="1"></button>
75
+ <button type="button" class="button_prev_file" data-shortcut="["></button>
76
+ <button type="button" class="button_next_file" data-shortcut="]"></button>
77
+ <button type="button" class="button_to_index" data-shortcut="u"></button>
78
+ <button type="button" class="button_show_hide_help" data-shortcut="?"></button>
79
+ </aside>
80
+ </div>
81
+ </header>
82
+ <main id="source">
83
+ <p class="pln"><span class="n"><a id="t1" href="#t1">1</a></span><span class="t"><span class="str">"""Component-level OpenTelemetry instrumentation for Golf-built servers."""</span>&nbsp;</span><span class="r"></span></p>
84
+ <p class="pln"><span class="n"><a id="t2" href="#t2">2</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
85
+ <p class="mis show_mis"><span class="n"><a id="t3" href="#t3">3</a></span><span class="t"><span class="key">import</span> <span class="nam">asyncio</span>&nbsp;</span><span class="r"></span></p>
86
+ <p class="mis show_mis"><span class="n"><a id="t4" href="#t4">4</a></span><span class="t"><span class="key">import</span> <span class="nam">functools</span>&nbsp;</span><span class="r"></span></p>
87
+ <p class="mis show_mis"><span class="n"><a id="t5" href="#t5">5</a></span><span class="t"><span class="key">import</span> <span class="nam">os</span>&nbsp;</span><span class="r"></span></p>
88
+ <p class="mis show_mis"><span class="n"><a id="t6" href="#t6">6</a></span><span class="t"><span class="key">import</span> <span class="nam">sys</span>&nbsp;</span><span class="r"></span></p>
89
+ <p class="mis show_mis"><span class="n"><a id="t7" href="#t7">7</a></span><span class="t"><span class="key">import</span> <span class="nam">time</span>&nbsp;</span><span class="r"></span></p>
90
+ <p class="mis show_mis"><span class="n"><a id="t8" href="#t8">8</a></span><span class="t"><span class="key">import</span> <span class="nam">json</span>&nbsp;</span><span class="r"></span></p>
91
+ <p class="mis show_mis"><span class="n"><a id="t9" href="#t9">9</a></span><span class="t"><span class="key">from</span> <span class="nam">collections</span><span class="op">.</span><span class="nam">abc</span> <span class="key">import</span> <span class="nam">Callable</span>&nbsp;</span><span class="r"></span></p>
92
+ <p class="mis show_mis"><span class="n"><a id="t10" href="#t10">10</a></span><span class="t"><span class="key">from</span> <span class="nam">contextlib</span> <span class="key">import</span> <span class="nam">asynccontextmanager</span>&nbsp;</span><span class="r"></span></p>
93
+ <p class="mis show_mis"><span class="n"><a id="t11" href="#t11">11</a></span><span class="t"><span class="key">from</span> <span class="nam">typing</span> <span class="key">import</span> <span class="nam">Any</span><span class="op">,</span> <span class="nam">TypeVar</span>&nbsp;</span><span class="r"></span></p>
94
+ <p class="mis show_mis"><span class="n"><a id="t12" href="#t12">12</a></span><span class="t"><span class="key">from</span> <span class="nam">collections</span><span class="op">.</span><span class="nam">abc</span> <span class="key">import</span> <span class="nam">AsyncGenerator</span>&nbsp;</span><span class="r"></span></p>
95
+ <p class="mis show_mis"><span class="n"><a id="t13" href="#t13">13</a></span><span class="t"><span class="key">from</span> <span class="nam">collections</span> <span class="key">import</span> <span class="nam">OrderedDict</span>&nbsp;</span><span class="r"></span></p>
96
+ <p class="pln"><span class="n"><a id="t14" href="#t14">14</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
97
+ <p class="mis show_mis"><span class="n"><a id="t15" href="#t15">15</a></span><span class="t"><span class="key">from</span> <span class="nam">opentelemetry</span> <span class="key">import</span> <span class="nam">baggage</span><span class="op">,</span> <span class="nam">trace</span>&nbsp;</span><span class="r"></span></p>
98
+ <p class="pln"><span class="n"><a id="t16" href="#t16">16</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
99
+ <p class="pln"><span class="n"><a id="t17" href="#t17">17</a></span><span class="t"><span class="com"># Import endpoints with fallback for dev mode</span>&nbsp;</span><span class="r"></span></p>
100
+ <p class="mis show_mis"><span class="n"><a id="t18" href="#t18">18</a></span><span class="t"><span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
101
+ <p class="pln"><span class="n"><a id="t19" href="#t19">19</a></span><span class="t"> <span class="com"># In built wheels, this exists (generated from _endpoints.py.in)</span>&nbsp;</span><span class="r"></span></p>
102
+ <p class="mis show_mis"><span class="n"><a id="t20" href="#t20">20</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span> <span class="key">import</span> <span class="nam">_endpoints</span> <span class="com"># type: ignore</span>&nbsp;</span><span class="r"></span></p>
103
+ <p class="mis show_mis"><span class="n"><a id="t21" href="#t21">21</a></span><span class="t"><span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
104
+ <p class="pln"><span class="n"><a id="t22" href="#t22">22</a></span><span class="t"> <span class="com"># In editable/dev installs, fall back to env-based values</span>&nbsp;</span><span class="r"></span></p>
105
+ <p class="mis show_mis"><span class="n"><a id="t23" href="#t23">23</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span> <span class="key">import</span> <span class="nam">_endpoints_fallback</span> <span class="key">as</span> <span class="nam">_endpoints</span> <span class="com"># type: ignore</span>&nbsp;</span><span class="r"></span></p>
106
+ <p class="mis show_mis"><span class="n"><a id="t24" href="#t24">24</a></span><span class="t"><span class="key">from</span> <span class="nam">opentelemetry</span><span class="op">.</span><span class="nam">exporter</span><span class="op">.</span><span class="nam">otlp</span><span class="op">.</span><span class="nam">proto</span><span class="op">.</span><span class="nam">http</span><span class="op">.</span><span class="nam">trace_exporter</span> <span class="key">import</span> <span class="nam">OTLPSpanExporter</span>&nbsp;</span><span class="r"></span></p>
107
+ <p class="mis show_mis"><span class="n"><a id="t25" href="#t25">25</a></span><span class="t"><span class="key">from</span> <span class="nam">opentelemetry</span><span class="op">.</span><span class="nam">sdk</span><span class="op">.</span><span class="nam">resources</span> <span class="key">import</span> <span class="nam">Resource</span>&nbsp;</span><span class="r"></span></p>
108
+ <p class="mis show_mis"><span class="n"><a id="t26" href="#t26">26</a></span><span class="t"><span class="key">from</span> <span class="nam">opentelemetry</span><span class="op">.</span><span class="nam">sdk</span><span class="op">.</span><span class="nam">trace</span> <span class="key">import</span> <span class="nam">TracerProvider</span>&nbsp;</span><span class="r"></span></p>
109
+ <p class="mis show_mis"><span class="n"><a id="t27" href="#t27">27</a></span><span class="t"><span class="key">from</span> <span class="nam">opentelemetry</span><span class="op">.</span><span class="nam">sdk</span><span class="op">.</span><span class="nam">trace</span><span class="op">.</span><span class="nam">export</span> <span class="key">import</span> <span class="nam">BatchSpanProcessor</span><span class="op">,</span> <span class="nam">ConsoleSpanExporter</span>&nbsp;</span><span class="r"></span></p>
110
+ <p class="mis show_mis"><span class="n"><a id="t28" href="#t28">28</a></span><span class="t"><span class="key">from</span> <span class="nam">opentelemetry</span><span class="op">.</span><span class="nam">trace</span> <span class="key">import</span> <span class="nam">Status</span><span class="op">,</span> <span class="nam">StatusCode</span>&nbsp;</span><span class="r"></span></p>
111
+ <p class="pln"><span class="n"><a id="t29" href="#t29">29</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
112
+ <p class="mis show_mis"><span class="n"><a id="t30" href="#t30">30</a></span><span class="t"><span class="key">from</span> <span class="nam">starlette</span><span class="op">.</span><span class="nam">middleware</span><span class="op">.</span><span class="nam">base</span> <span class="key">import</span> <span class="nam">BaseHTTPMiddleware</span>&nbsp;</span><span class="r"></span></p>
113
+ <p class="pln"><span class="n"><a id="t31" href="#t31">31</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
114
+ <p class="mis show_mis"><span class="n"><a id="t32" href="#t32">32</a></span><span class="t"><span class="nam">T</span> <span class="op">=</span> <span class="nam">TypeVar</span><span class="op">(</span><span class="str">"T"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
115
+ <p class="pln"><span class="n"><a id="t33" href="#t33">33</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
116
+ <p class="pln"><span class="n"><a id="t34" href="#t34">34</a></span><span class="t"><span class="com"># Global tracer instance</span>&nbsp;</span><span class="r"></span></p>
117
+ <p class="mis show_mis"><span class="n"><a id="t35" href="#t35">35</a></span><span class="t"><span class="nam">_tracer</span><span class="op">:</span> <span class="nam">trace</span><span class="op">.</span><span class="nam">Tracer</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
118
+ <p class="mis show_mis"><span class="n"><a id="t36" href="#t36">36</a></span><span class="t"><span class="nam">_provider</span><span class="op">:</span> <span class="nam">TracerProvider</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
119
+ <p class="mis show_mis"><span class="n"><a id="t37" href="#t37">37</a></span><span class="t"><span class="nam">_detailed_tracing_enabled</span><span class="op">:</span> <span class="nam">bool</span> <span class="op">=</span> <span class="key">False</span>&nbsp;</span><span class="r"></span></p>
120
+ <p class="pln"><span class="n"><a id="t38" href="#t38">38</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
121
+ <p class="pln"><span class="n"><a id="t39" href="#t39">39</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
122
+ <p class="mis show_mis"><span class="n"><a id="t40" href="#t40">40</a></span><span class="t"><span class="key">def</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">data</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="nam">max_length</span><span class="op">:</span> <span class="nam">int</span> <span class="op">=</span> <span class="num">1000</span><span class="op">)</span> <span class="op">-></span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
123
+ <p class="pln"><span class="n"><a id="t41" href="#t41">41</a></span><span class="t"> <span class="str">"""Safely serialize data to string with length limit."""</span>&nbsp;</span><span class="r"></span></p>
124
+ <p class="mis show_mis"><span class="n"><a id="t42" href="#t42">42</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
125
+ <p class="mis show_mis"><span class="n"><a id="t43" href="#t43">43</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">data</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
126
+ <p class="mis show_mis"><span class="n"><a id="t44" href="#t44">44</a></span><span class="t"> <span class="nam">serialized</span> <span class="op">=</span> <span class="nam">data</span>&nbsp;</span><span class="r"></span></p>
127
+ <p class="pln"><span class="n"><a id="t45" href="#t45">45</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
128
+ <p class="mis show_mis"><span class="n"><a id="t46" href="#t46">46</a></span><span class="t"> <span class="nam">serialized</span> <span class="op">=</span> <span class="nam">json</span><span class="op">.</span><span class="nam">dumps</span><span class="op">(</span><span class="nam">data</span><span class="op">,</span> <span class="nam">default</span><span class="op">=</span><span class="nam">str</span><span class="op">,</span> <span class="nam">ensure_ascii</span><span class="op">=</span><span class="key">False</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
129
+ <p class="pln"><span class="n"><a id="t47" href="#t47">47</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
130
+ <p class="mis show_mis"><span class="n"><a id="t48" href="#t48">48</a></span><span class="t"> <span class="key">if</span> <span class="nam">len</span><span class="op">(</span><span class="nam">serialized</span><span class="op">)</span> <span class="op">></span> <span class="nam">max_length</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
131
+ <p class="mis show_mis"><span class="n"><a id="t49" href="#t49">49</a></span><span class="t"> <span class="key">return</span> <span class="nam">serialized</span><span class="op">[</span><span class="op">:</span><span class="nam">max_length</span><span class="op">]</span> <span class="op">+</span> <span class="str">"..."</span> <span class="op">+</span> <span class="str">f" (truncated from {len(serialized)} chars)"</span>&nbsp;</span><span class="r"></span></p>
132
+ <p class="mis show_mis"><span class="n"><a id="t50" href="#t50">50</a></span><span class="t"> <span class="key">return</span> <span class="nam">serialized</span>&nbsp;</span><span class="r"></span></p>
133
+ <p class="mis show_mis"><span class="n"><a id="t51" href="#t51">51</a></span><span class="t"> <span class="key">except</span> <span class="op">(</span><span class="nam">TypeError</span><span class="op">,</span> <span class="nam">ValueError</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
134
+ <p class="pln"><span class="n"><a id="t52" href="#t52">52</a></span><span class="t"> <span class="com"># Fallback for non-serializable objects</span>&nbsp;</span><span class="r"></span></p>
135
+ <p class="mis show_mis"><span class="n"><a id="t53" href="#t53">53</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
136
+ <p class="mis show_mis"><span class="n"><a id="t54" href="#t54">54</a></span><span class="t"> <span class="key">return</span> <span class="nam">str</span><span class="op">(</span><span class="nam">data</span><span class="op">)</span><span class="op">[</span><span class="op">:</span><span class="nam">max_length</span><span class="op">]</span> <span class="op">+</span> <span class="str">"..."</span> <span class="key">if</span> <span class="nam">len</span><span class="op">(</span><span class="nam">str</span><span class="op">(</span><span class="nam">data</span><span class="op">)</span><span class="op">)</span> <span class="op">></span> <span class="nam">max_length</span> <span class="key">else</span> <span class="nam">str</span><span class="op">(</span><span class="nam">data</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
137
+ <p class="mis show_mis"><span class="n"><a id="t55" href="#t55">55</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
138
+ <p class="mis show_mis"><span class="n"><a id="t56" href="#t56">56</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
139
+ <p class="pln"><span class="n"><a id="t57" href="#t57">57</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
140
+ <p class="pln"><span class="n"><a id="t58" href="#t58">58</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
141
+ <p class="mis show_mis"><span class="n"><a id="t59" href="#t59">59</a></span><span class="t"><span class="key">def</span> <span class="nam">set_detailed_tracing</span><span class="op">(</span><span class="nam">enabled</span><span class="op">:</span> <span class="nam">bool</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
142
+ <p class="pln"><span class="n"><a id="t60" href="#t60">60</a></span><span class="t"> <span class="str">"""Enable or disable detailed tracing with input/output capture."""</span>&nbsp;</span><span class="r"></span></p>
143
+ <p class="pln"><span class="n"><a id="t61" href="#t61">61</a></span><span class="t"> <span class="key">global</span> <span class="nam">_detailed_tracing_enabled</span>&nbsp;</span><span class="r"></span></p>
144
+ <p class="mis show_mis"><span class="n"><a id="t62" href="#t62">62</a></span><span class="t"> <span class="nam">_detailed_tracing_enabled</span> <span class="op">=</span> <span class="nam">enabled</span>&nbsp;</span><span class="r"></span></p>
145
+ <p class="pln"><span class="n"><a id="t63" href="#t63">63</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
146
+ <p class="pln"><span class="n"><a id="t64" href="#t64">64</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
147
+ <p class="mis show_mis"><span class="n"><a id="t65" href="#t65">65</a></span><span class="t"><span class="key">def</span> <span class="nam">init_telemetry</span><span class="op">(</span><span class="nam">service_name</span><span class="op">:</span> <span class="nam">str</span> <span class="op">=</span> <span class="str">"golf-mcp-server"</span><span class="op">)</span> <span class="op">-></span> <span class="nam">TracerProvider</span> <span class="op">|</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
148
+ <p class="pln"><span class="n"><a id="t66" href="#t66">66</a></span><span class="t"> <span class="str">"""Initialize OpenTelemetry with environment-based configuration.</span>&nbsp;</span><span class="r"></span></p>
149
+ <p class="pln"><span class="n"><a id="t67" href="#t67">67</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
150
+ <p class="pln"><span class="n"><a id="t68" href="#t68">68</a></span><span class="t"><span class="str"> Returns None if required environment variables are not set.</span>&nbsp;</span><span class="r"></span></p>
151
+ <p class="pln"><span class="n"><a id="t69" href="#t69">69</a></span><span class="t"><span class="str"> """</span>&nbsp;</span><span class="r"></span></p>
152
+ <p class="pln"><span class="n"><a id="t70" href="#t70">70</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
153
+ <p class="pln"><span class="n"><a id="t71" href="#t71">71</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
154
+ <p class="pln"><span class="n"><a id="t72" href="#t72">72</a></span><span class="t"> <span class="com"># Check for Golf platform integration first</span>&nbsp;</span><span class="r"></span></p>
155
+ <p class="mis show_mis"><span class="n"><a id="t73" href="#t73">73</a></span><span class="t"> <span class="nam">golf_api_key</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"GOLF_API_KEY"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
156
+ <p class="mis show_mis"><span class="n"><a id="t74" href="#t74">74</a></span><span class="t"> <span class="key">if</span> <span class="nam">golf_api_key</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
157
+ <p class="pln"><span class="n"><a id="t75" href="#t75">75</a></span><span class="t"> <span class="com"># Auto-configure for Golf platform - always use OTLP when Golf API</span>&nbsp;</span><span class="r"></span></p>
158
+ <p class="pln"><span class="n"><a id="t76" href="#t76">76</a></span><span class="t"> <span class="com"># key is present</span>&nbsp;</span><span class="r"></span></p>
159
+ <p class="mis show_mis"><span class="n"><a id="t77" href="#t77">77</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">[</span><span class="str">"OTEL_TRACES_EXPORTER"</span><span class="op">]</span> <span class="op">=</span> <span class="str">"otlp_http"</span>&nbsp;</span><span class="r"></span></p>
160
+ <p class="pln"><span class="n"><a id="t78" href="#t78">78</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
161
+ <p class="pln"><span class="n"><a id="t79" href="#t79">79</a></span><span class="t"> <span class="com"># Only set endpoint if not already configured (allow user override)</span>&nbsp;</span><span class="r"></span></p>
162
+ <p class="mis show_mis"><span class="n"><a id="t80" href="#t80">80</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_EXPORTER_OTLP_ENDPOINT"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
163
+ <p class="mis show_mis"><span class="n"><a id="t81" href="#t81">81</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">[</span><span class="str">"OTEL_EXPORTER_OTLP_ENDPOINT"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">_endpoints</span><span class="op">.</span><span class="nam">OTEL_ENDPOINT</span>&nbsp;</span><span class="r"></span></p>
164
+ <p class="pln"><span class="n"><a id="t82" href="#t82">82</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
165
+ <p class="pln"><span class="n"><a id="t83" href="#t83">83</a></span><span class="t"> <span class="com"># Set Golf platform headers (append to existing if present)</span>&nbsp;</span><span class="r"></span></p>
166
+ <p class="mis show_mis"><span class="n"><a id="t84" href="#t84">84</a></span><span class="t"> <span class="nam">existing_headers</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_EXPORTER_OTLP_HEADERS"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
167
+ <p class="mis show_mis"><span class="n"><a id="t85" href="#t85">85</a></span><span class="t"> <span class="nam">golf_header</span> <span class="op">=</span> <span class="str">f"X-Golf-Key={golf_api_key}"</span>&nbsp;</span><span class="r"></span></p>
168
+ <p class="pln"><span class="n"><a id="t86" href="#t86">86</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
169
+ <p class="mis show_mis"><span class="n"><a id="t87" href="#t87">87</a></span><span class="t"> <span class="key">if</span> <span class="nam">existing_headers</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
170
+ <p class="pln"><span class="n"><a id="t88" href="#t88">88</a></span><span class="t"> <span class="com"># Check if Golf key is already in headers</span>&nbsp;</span><span class="r"></span></p>
171
+ <p class="mis show_mis"><span class="n"><a id="t89" href="#t89">89</a></span><span class="t"> <span class="key">if</span> <span class="str">"X-Golf-Key="</span> <span class="key">not</span> <span class="key">in</span> <span class="nam">existing_headers</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
172
+ <p class="mis show_mis"><span class="n"><a id="t90" href="#t90">90</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">[</span><span class="str">"OTEL_EXPORTER_OTLP_HEADERS"</span><span class="op">]</span> <span class="op">=</span> <span class="str">f"{existing_headers},{golf_header}"</span>&nbsp;</span><span class="r"></span></p>
173
+ <p class="pln"><span class="n"><a id="t91" href="#t91">91</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
174
+ <p class="mis show_mis"><span class="n"><a id="t92" href="#t92">92</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">[</span><span class="str">"OTEL_EXPORTER_OTLP_HEADERS"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">golf_header</span>&nbsp;</span><span class="r"></span></p>
175
+ <p class="pln"><span class="n"><a id="t93" href="#t93">93</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
176
+ <p class="pln"><span class="n"><a id="t94" href="#t94">94</a></span><span class="t"> <span class="com"># Check for required environment variables based on exporter type</span>&nbsp;</span><span class="r"></span></p>
177
+ <p class="mis show_mis"><span class="n"><a id="t95" href="#t95">95</a></span><span class="t"> <span class="nam">exporter_type</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_TRACES_EXPORTER"</span><span class="op">,</span> <span class="str">"console"</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
178
+ <p class="pln"><span class="n"><a id="t96" href="#t96">96</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
179
+ <p class="pln"><span class="n"><a id="t97" href="#t97">97</a></span><span class="t"> <span class="com"># For OTLP HTTP exporter, check if endpoint is configured</span>&nbsp;</span><span class="r"></span></p>
180
+ <p class="mis show_mis"><span class="n"><a id="t98" href="#t98">98</a></span><span class="t"> <span class="key">if</span> <span class="nam">exporter_type</span> <span class="op">==</span> <span class="str">"otlp_http"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
181
+ <p class="mis show_mis"><span class="n"><a id="t99" href="#t99">99</a></span><span class="t"> <span class="nam">endpoint</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_EXPORTER_OTLP_ENDPOINT"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
182
+ <p class="mis show_mis"><span class="n"><a id="t100" href="#t100">100</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">endpoint</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
183
+ <p class="mis show_mis"><span class="n"><a id="t101" href="#t101">101</a></span><span class="t"> <span class="nam">print</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
184
+ <p class="pln"><span class="n"><a id="t102" href="#t102">102</a></span><span class="t"> <span class="str">"[WARNING] OpenTelemetry tracing is disabled: "</span>&nbsp;</span><span class="r"></span></p>
185
+ <p class="pln"><span class="n"><a id="t103" href="#t103">103</a></span><span class="t"> <span class="str">"OTEL_EXPORTER_OTLP_ENDPOINT is not set for OTLP HTTP exporter"</span>&nbsp;</span><span class="r"></span></p>
186
+ <p class="pln"><span class="n"><a id="t104" href="#t104">104</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
187
+ <p class="mis show_mis"><span class="n"><a id="t105" href="#t105">105</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
188
+ <p class="pln"><span class="n"><a id="t106" href="#t106">106</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
189
+ <p class="pln"><span class="n"><a id="t107" href="#t107">107</a></span><span class="t"> <span class="com"># Create resource with service information</span>&nbsp;</span><span class="r"></span></p>
190
+ <p class="mis show_mis"><span class="n"><a id="t108" href="#t108">108</a></span><span class="t"> <span class="nam">resource_attributes</span> <span class="op">=</span> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
191
+ <p class="pln"><span class="n"><a id="t109" href="#t109">109</a></span><span class="t"> <span class="str">"service.name"</span><span class="op">:</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_SERVICE_NAME"</span><span class="op">,</span> <span class="nam">service_name</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
192
+ <p class="pln"><span class="n"><a id="t110" href="#t110">110</a></span><span class="t"> <span class="str">"service.version"</span><span class="op">:</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"SERVICE_VERSION"</span><span class="op">,</span> <span class="str">"1.0.0"</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
193
+ <p class="pln"><span class="n"><a id="t111" href="#t111">111</a></span><span class="t"> <span class="str">"service.instance.id"</span><span class="op">:</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"SERVICE_INSTANCE_ID"</span><span class="op">,</span> <span class="str">"default"</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
194
+ <p class="pln"><span class="n"><a id="t112" href="#t112">112</a></span><span class="t"> <span class="op">}</span>&nbsp;</span><span class="r"></span></p>
195
+ <p class="pln"><span class="n"><a id="t113" href="#t113">113</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
196
+ <p class="pln"><span class="n"><a id="t114" href="#t114">114</a></span><span class="t"> <span class="com"># Add Golf-specific attributes if available</span>&nbsp;</span><span class="r"></span></p>
197
+ <p class="mis show_mis"><span class="n"><a id="t115" href="#t115">115</a></span><span class="t"> <span class="key">if</span> <span class="nam">golf_api_key</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
198
+ <p class="mis show_mis"><span class="n"><a id="t116" href="#t116">116</a></span><span class="t"> <span class="nam">golf_server_id</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"GOLF_SERVER_ID"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
199
+ <p class="mis show_mis"><span class="n"><a id="t117" href="#t117">117</a></span><span class="t"> <span class="key">if</span> <span class="nam">golf_server_id</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
200
+ <p class="mis show_mis"><span class="n"><a id="t118" href="#t118">118</a></span><span class="t"> <span class="nam">resource_attributes</span><span class="op">[</span><span class="str">"golf.server.id"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">golf_server_id</span>&nbsp;</span><span class="r"></span></p>
201
+ <p class="mis show_mis"><span class="n"><a id="t119" href="#t119">119</a></span><span class="t"> <span class="nam">resource_attributes</span><span class="op">[</span><span class="str">"golf.platform.enabled"</span><span class="op">]</span> <span class="op">=</span> <span class="str">"true"</span>&nbsp;</span><span class="r"></span></p>
202
+ <p class="pln"><span class="n"><a id="t120" href="#t120">120</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
203
+ <p class="mis show_mis"><span class="n"><a id="t121" href="#t121">121</a></span><span class="t"> <span class="nam">resource</span> <span class="op">=</span> <span class="nam">Resource</span><span class="op">.</span><span class="nam">create</span><span class="op">(</span><span class="nam">resource_attributes</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
204
+ <p class="pln"><span class="n"><a id="t122" href="#t122">122</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
205
+ <p class="pln"><span class="n"><a id="t123" href="#t123">123</a></span><span class="t"> <span class="com"># Create provider</span>&nbsp;</span><span class="r"></span></p>
206
+ <p class="mis show_mis"><span class="n"><a id="t124" href="#t124">124</a></span><span class="t"> <span class="nam">provider</span> <span class="op">=</span> <span class="nam">TracerProvider</span><span class="op">(</span><span class="nam">resource</span><span class="op">=</span><span class="nam">resource</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
207
+ <p class="pln"><span class="n"><a id="t125" href="#t125">125</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
208
+ <p class="pln"><span class="n"><a id="t126" href="#t126">126</a></span><span class="t"> <span class="com"># Configure exporter based on type</span>&nbsp;</span><span class="r"></span></p>
209
+ <p class="mis show_mis"><span class="n"><a id="t127" href="#t127">127</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
210
+ <p class="mis show_mis"><span class="n"><a id="t128" href="#t128">128</a></span><span class="t"> <span class="key">if</span> <span class="nam">exporter_type</span> <span class="op">==</span> <span class="str">"otlp_http"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
211
+ <p class="mis show_mis"><span class="n"><a id="t129" href="#t129">129</a></span><span class="t"> <span class="nam">endpoint</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_EXPORTER_OTLP_ENDPOINT"</span><span class="op">,</span> <span class="str">"http://localhost:4318/v1/traces"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
212
+ <p class="mis show_mis"><span class="n"><a id="t130" href="#t130">130</a></span><span class="t"> <span class="nam">headers</span> <span class="op">=</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"OTEL_EXPORTER_OTLP_HEADERS"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
213
+ <p class="pln"><span class="n"><a id="t131" href="#t131">131</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
214
+ <p class="pln"><span class="n"><a id="t132" href="#t132">132</a></span><span class="t"> <span class="com"># Parse headers if provided</span>&nbsp;</span><span class="r"></span></p>
215
+ <p class="mis show_mis"><span class="n"><a id="t133" href="#t133">133</a></span><span class="t"> <span class="nam">header_dict</span> <span class="op">=</span> <span class="op">{</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
216
+ <p class="mis show_mis"><span class="n"><a id="t134" href="#t134">134</a></span><span class="t"> <span class="key">if</span> <span class="nam">headers</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
217
+ <p class="mis show_mis"><span class="n"><a id="t135" href="#t135">135</a></span><span class="t"> <span class="key">for</span> <span class="nam">header</span> <span class="key">in</span> <span class="nam">headers</span><span class="op">.</span><span class="nam">split</span><span class="op">(</span><span class="str">","</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
218
+ <p class="mis show_mis"><span class="n"><a id="t136" href="#t136">136</a></span><span class="t"> <span class="key">if</span> <span class="str">"="</span> <span class="key">in</span> <span class="nam">header</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
219
+ <p class="mis show_mis"><span class="n"><a id="t137" href="#t137">137</a></span><span class="t"> <span class="nam">key</span><span class="op">,</span> <span class="nam">value</span> <span class="op">=</span> <span class="nam">header</span><span class="op">.</span><span class="nam">split</span><span class="op">(</span><span class="str">"="</span><span class="op">,</span> <span class="num">1</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
220
+ <p class="mis show_mis"><span class="n"><a id="t138" href="#t138">138</a></span><span class="t"> <span class="nam">header_dict</span><span class="op">[</span><span class="nam">key</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span><span class="op">]</span> <span class="op">=</span> <span class="nam">value</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
221
+ <p class="pln"><span class="n"><a id="t139" href="#t139">139</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
222
+ <p class="mis show_mis"><span class="n"><a id="t140" href="#t140">140</a></span><span class="t"> <span class="nam">exporter</span> <span class="op">=</span> <span class="nam">OTLPSpanExporter</span><span class="op">(</span><span class="nam">endpoint</span><span class="op">=</span><span class="nam">endpoint</span><span class="op">,</span> <span class="nam">headers</span><span class="op">=</span><span class="nam">header_dict</span> <span class="key">if</span> <span class="nam">header_dict</span> <span class="key">else</span> <span class="key">None</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
223
+ <p class="pln"><span class="n"><a id="t141" href="#t141">141</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
224
+ <p class="pln"><span class="n"><a id="t142" href="#t142">142</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
225
+ <p class="pln"><span class="n"><a id="t143" href="#t143">143</a></span><span class="t"> <span class="com"># Default to console exporter</span>&nbsp;</span><span class="r"></span></p>
226
+ <p class="mis show_mis"><span class="n"><a id="t144" href="#t144">144</a></span><span class="t"> <span class="nam">exporter</span> <span class="op">=</span> <span class="nam">ConsoleSpanExporter</span><span class="op">(</span><span class="nam">out</span><span class="op">=</span><span class="nam">sys</span><span class="op">.</span><span class="nam">stderr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
227
+ <p class="mis show_mis"><span class="n"><a id="t145" href="#t145">145</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
228
+ <p class="mis show_mis"><span class="n"><a id="t146" href="#t146">146</a></span><span class="t"> <span class="key">import</span> <span class="nam">traceback</span>&nbsp;</span><span class="r"></span></p>
229
+ <p class="pln"><span class="n"><a id="t147" href="#t147">147</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
230
+ <p class="mis show_mis"><span class="n"><a id="t148" href="#t148">148</a></span><span class="t"> <span class="nam">traceback</span><span class="op">.</span><span class="nam">print_exc</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
231
+ <p class="mis show_mis"><span class="n"><a id="t149" href="#t149">149</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
232
+ <p class="pln"><span class="n"><a id="t150" href="#t150">150</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
233
+ <p class="pln"><span class="n"><a id="t151" href="#t151">151</a></span><span class="t"> <span class="com"># Add batch processor for better performance</span>&nbsp;</span><span class="r"></span></p>
234
+ <p class="mis show_mis"><span class="n"><a id="t152" href="#t152">152</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
235
+ <p class="mis show_mis"><span class="n"><a id="t153" href="#t153">153</a></span><span class="t"> <span class="nam">processor</span> <span class="op">=</span> <span class="nam">BatchSpanProcessor</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
236
+ <p class="pln"><span class="n"><a id="t154" href="#t154">154</a></span><span class="t"> <span class="nam">exporter</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
237
+ <p class="pln"><span class="n"><a id="t155" href="#t155">155</a></span><span class="t"> <span class="nam">max_queue_size</span><span class="op">=</span><span class="num">2048</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
238
+ <p class="pln"><span class="n"><a id="t156" href="#t156">156</a></span><span class="t"> <span class="nam">schedule_delay_millis</span><span class="op">=</span><span class="num">1000</span><span class="op">,</span> <span class="com"># Export every 1 second instead of</span>&nbsp;</span><span class="r"></span></p>
239
+ <p class="pln"><span class="n"><a id="t157" href="#t157">157</a></span><span class="t"> <span class="com"># default 5 seconds</span>&nbsp;</span><span class="r"></span></p>
240
+ <p class="pln"><span class="n"><a id="t158" href="#t158">158</a></span><span class="t"> <span class="nam">max_export_batch_size</span><span class="op">=</span><span class="num">512</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
241
+ <p class="pln"><span class="n"><a id="t159" href="#t159">159</a></span><span class="t"> <span class="nam">export_timeout_millis</span><span class="op">=</span><span class="num">5000</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
242
+ <p class="pln"><span class="n"><a id="t160" href="#t160">160</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
243
+ <p class="mis show_mis"><span class="n"><a id="t161" href="#t161">161</a></span><span class="t"> <span class="nam">provider</span><span class="op">.</span><span class="nam">add_span_processor</span><span class="op">(</span><span class="nam">processor</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
244
+ <p class="mis show_mis"><span class="n"><a id="t162" href="#t162">162</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
245
+ <p class="mis show_mis"><span class="n"><a id="t163" href="#t163">163</a></span><span class="t"> <span class="key">import</span> <span class="nam">traceback</span>&nbsp;</span><span class="r"></span></p>
246
+ <p class="pln"><span class="n"><a id="t164" href="#t164">164</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
247
+ <p class="mis show_mis"><span class="n"><a id="t165" href="#t165">165</a></span><span class="t"> <span class="nam">traceback</span><span class="op">.</span><span class="nam">print_exc</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
248
+ <p class="mis show_mis"><span class="n"><a id="t166" href="#t166">166</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
249
+ <p class="pln"><span class="n"><a id="t167" href="#t167">167</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
250
+ <p class="pln"><span class="n"><a id="t168" href="#t168">168</a></span><span class="t"> <span class="com"># Set as global provider</span>&nbsp;</span><span class="r"></span></p>
251
+ <p class="mis show_mis"><span class="n"><a id="t169" href="#t169">169</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
252
+ <p class="pln"><span class="n"><a id="t170" href="#t170">170</a></span><span class="t"> <span class="com"># Check if a provider is already set to avoid the warning</span>&nbsp;</span><span class="r"></span></p>
253
+ <p class="mis show_mis"><span class="n"><a id="t171" href="#t171">171</a></span><span class="t"> <span class="nam">existing_provider</span> <span class="op">=</span> <span class="nam">trace</span><span class="op">.</span><span class="nam">get_tracer_provider</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
254
+ <p class="mis show_mis"><span class="n"><a id="t172" href="#t172">172</a></span><span class="t"> <span class="key">if</span> <span class="nam">existing_provider</span> <span class="key">is</span> <span class="key">None</span> <span class="key">or</span> <span class="nam">str</span><span class="op">(</span><span class="nam">type</span><span class="op">(</span><span class="nam">existing_provider</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span> <span class="op">==</span> <span class="str">"ProxyTracerProvider"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
255
+ <p class="pln"><span class="n"><a id="t173" href="#t173">173</a></span><span class="t"> <span class="com"># Only set if no provider exists or it's the default proxy provider</span>&nbsp;</span><span class="r"></span></p>
256
+ <p class="mis show_mis"><span class="n"><a id="t174" href="#t174">174</a></span><span class="t"> <span class="nam">trace</span><span class="op">.</span><span class="nam">set_tracer_provider</span><span class="op">(</span><span class="nam">provider</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
257
+ <p class="mis show_mis"><span class="n"><a id="t175" href="#t175">175</a></span><span class="t"> <span class="nam">_provider</span> <span class="op">=</span> <span class="nam">provider</span>&nbsp;</span><span class="r"></span></p>
258
+ <p class="mis show_mis"><span class="n"><a id="t176" href="#t176">176</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
259
+ <p class="mis show_mis"><span class="n"><a id="t177" href="#t177">177</a></span><span class="t"> <span class="key">import</span> <span class="nam">traceback</span>&nbsp;</span><span class="r"></span></p>
260
+ <p class="pln"><span class="n"><a id="t178" href="#t178">178</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
261
+ <p class="mis show_mis"><span class="n"><a id="t179" href="#t179">179</a></span><span class="t"> <span class="nam">traceback</span><span class="op">.</span><span class="nam">print_exc</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
262
+ <p class="mis show_mis"><span class="n"><a id="t180" href="#t180">180</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
263
+ <p class="pln"><span class="n"><a id="t181" href="#t181">181</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
264
+ <p class="mis show_mis"><span class="n"><a id="t182" href="#t182">182</a></span><span class="t"> <span class="key">return</span> <span class="nam">provider</span>&nbsp;</span><span class="r"></span></p>
265
+ <p class="pln"><span class="n"><a id="t183" href="#t183">183</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
266
+ <p class="pln"><span class="n"><a id="t184" href="#t184">184</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
267
+ <p class="mis show_mis"><span class="n"><a id="t185" href="#t185">185</a></span><span class="t"><span class="key">def</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span> <span class="op">-></span> <span class="nam">trace</span><span class="op">.</span><span class="nam">Tracer</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
268
+ <p class="pln"><span class="n"><a id="t186" href="#t186">186</a></span><span class="t"> <span class="str">"""Get or create the global tracer instance."""</span>&nbsp;</span><span class="r"></span></p>
269
+ <p class="pln"><span class="n"><a id="t187" href="#t187">187</a></span><span class="t"> <span class="key">global</span> <span class="nam">_tracer</span><span class="op">,</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
270
+ <p class="pln"><span class="n"><a id="t188" href="#t188">188</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
271
+ <p class="pln"><span class="n"><a id="t189" href="#t189">189</a></span><span class="t"> <span class="com"># If no provider is set, telemetry is disabled - return no-op tracer</span>&nbsp;</span><span class="r"></span></p>
272
+ <p class="mis show_mis"><span class="n"><a id="t190" href="#t190">190</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
273
+ <p class="mis show_mis"><span class="n"><a id="t191" href="#t191">191</a></span><span class="t"> <span class="key">return</span> <span class="nam">trace</span><span class="op">.</span><span class="nam">get_tracer</span><span class="op">(</span><span class="str">"golf.mcp.components.noop"</span><span class="op">,</span> <span class="str">"1.0.0"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
274
+ <p class="pln"><span class="n"><a id="t192" href="#t192">192</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
275
+ <p class="mis show_mis"><span class="n"><a id="t193" href="#t193">193</a></span><span class="t"> <span class="key">if</span> <span class="nam">_tracer</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
276
+ <p class="mis show_mis"><span class="n"><a id="t194" href="#t194">194</a></span><span class="t"> <span class="nam">_tracer</span> <span class="op">=</span> <span class="nam">trace</span><span class="op">.</span><span class="nam">get_tracer</span><span class="op">(</span><span class="str">"golf.mcp.components"</span><span class="op">,</span> <span class="str">"1.0.0"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
277
+ <p class="mis show_mis"><span class="n"><a id="t195" href="#t195">195</a></span><span class="t"> <span class="key">return</span> <span class="nam">_tracer</span>&nbsp;</span><span class="r"></span></p>
278
+ <p class="pln"><span class="n"><a id="t196" href="#t196">196</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
279
+ <p class="pln"><span class="n"><a id="t197" href="#t197">197</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
280
+ <p class="mis show_mis"><span class="n"><a id="t198" href="#t198">198</a></span><span class="t"><span class="key">def</span> <span class="nam">instrument_tool</span><span class="op">(</span><span class="nam">func</span><span class="op">:</span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">,</span> <span class="nam">tool_name</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
281
+ <p class="pln"><span class="n"><a id="t199" href="#t199">199</a></span><span class="t"> <span class="str">"""Instrument a tool function with OpenTelemetry tracing."""</span>&nbsp;</span><span class="r"></span></p>
282
+ <p class="pln"><span class="n"><a id="t200" href="#t200">200</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
283
+ <p class="pln"><span class="n"><a id="t201" href="#t201">201</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
284
+ <p class="pln"><span class="n"><a id="t202" href="#t202">202</a></span><span class="t"> <span class="com"># If telemetry is disabled, return the original function</span>&nbsp;</span><span class="r"></span></p>
285
+ <p class="mis show_mis"><span class="n"><a id="t203" href="#t203">203</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
286
+ <p class="mis show_mis"><span class="n"><a id="t204" href="#t204">204</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span>&nbsp;</span><span class="r"></span></p>
287
+ <p class="pln"><span class="n"><a id="t205" href="#t205">205</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
288
+ <p class="mis show_mis"><span class="n"><a id="t206" href="#t206">206</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
289
+ <p class="pln"><span class="n"><a id="t207" href="#t207">207</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
290
+ <p class="mis show_mis"><span class="n"><a id="t208" href="#t208">208</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
291
+ <p class="mis show_mis"><span class="n"><a id="t209" href="#t209">209</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">async_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
292
+ <p class="pln"><span class="n"><a id="t210" href="#t210">210</a></span><span class="t"> <span class="com"># Record metrics timing</span>&nbsp;</span><span class="r"></span></p>
293
+ <p class="mis show_mis"><span class="n"><a id="t211" href="#t211">211</a></span><span class="t"> <span class="key">import</span> <span class="nam">time</span>&nbsp;</span><span class="r"></span></p>
294
+ <p class="pln"><span class="n"><a id="t212" href="#t212">212</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
295
+ <p class="mis show_mis"><span class="n"><a id="t213" href="#t213">213</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
296
+ <p class="pln"><span class="n"><a id="t214" href="#t214">214</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
297
+ <p class="pln"><span class="n"><a id="t215" href="#t215">215</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
298
+ <p class="mis show_mis"><span class="n"><a id="t216" href="#t216">216</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.tool.{tool_name}.execute"</span>&nbsp;</span><span class="r"></span></p>
299
+ <p class="pln"><span class="n"><a id="t217" href="#t217">217</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
300
+ <p class="pln"><span class="n"><a id="t218" href="#t218">218</a></span><span class="t"> <span class="com"># start_as_current_span automatically uses the current context and manages it</span>&nbsp;</span><span class="r"></span></p>
301
+ <p class="mis show_mis"><span class="n"><a id="t219" href="#t219">219</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
302
+ <p class="pln"><span class="n"><a id="t220" href="#t220">220</a></span><span class="t"> <span class="com"># Add essential attributes only</span>&nbsp;</span><span class="r"></span></p>
303
+ <p class="mis show_mis"><span class="n"><a id="t221" href="#t221">221</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"tool"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
304
+ <p class="mis show_mis"><span class="n"><a id="t222" href="#t222">222</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.name"</span><span class="op">,</span> <span class="nam">tool_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
305
+ <p class="mis show_mis"><span class="n"><a id="t223" href="#t223">223</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
306
+ <p class="pln"><span class="n"><a id="t224" href="#t224">224</a></span><span class="t"> <span class="str">"mcp.tool.module"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
307
+ <p class="pln"><span class="n"><a id="t225" href="#t225">225</a></span><span class="t"> <span class="nam">func</span><span class="op">.</span><span class="nam">__module__</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="str">"__module__"</span><span class="op">)</span> <span class="key">else</span> <span class="str">"unknown"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
308
+ <p class="pln"><span class="n"><a id="t226" href="#t226">226</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
309
+ <p class="pln"><span class="n"><a id="t227" href="#t227">227</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
310
+ <p class="pln"><span class="n"><a id="t228" href="#t228">228</a></span><span class="t"> <span class="com"># Add minimal execution context</span>&nbsp;</span><span class="r"></span></p>
311
+ <p class="mis show_mis"><span class="n"><a id="t229" href="#t229">229</a></span><span class="t"> <span class="key">if</span> <span class="nam">args</span> <span class="key">or</span> <span class="nam">kwargs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
312
+ <p class="mis show_mis"><span class="n"><a id="t230" href="#t230">230</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.execution.has_params"</span><span class="op">,</span> <span class="key">True</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
313
+ <p class="pln"><span class="n"><a id="t231" href="#t231">231</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
314
+ <p class="pln"><span class="n"><a id="t232" href="#t232">232</a></span><span class="t"> <span class="com"># Capture inputs if detailed tracing is enabled</span>&nbsp;</span><span class="r"></span></p>
315
+ <p class="mis show_mis"><span class="n"><a id="t233" href="#t233">233</a></span><span class="t"> <span class="key">if</span> <span class="nam">_detailed_tracing_enabled</span> <span class="key">and</span> <span class="op">(</span><span class="nam">args</span> <span class="key">or</span> <span class="nam">kwargs</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
316
+ <p class="mis show_mis"><span class="n"><a id="t234" href="#t234">234</a></span><span class="t"> <span class="nam">input_data</span> <span class="op">=</span> <span class="op">{</span><span class="str">"args"</span><span class="op">:</span> <span class="nam">args</span><span class="op">,</span> <span class="str">"kwargs"</span><span class="op">:</span> <span class="nam">kwargs</span><span class="op">}</span> <span class="key">if</span> <span class="nam">args</span> <span class="key">or</span> <span class="nam">kwargs</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
317
+ <p class="mis show_mis"><span class="n"><a id="t235" href="#t235">235</a></span><span class="t"> <span class="key">if</span> <span class="nam">input_data</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
318
+ <p class="mis show_mis"><span class="n"><a id="t236" href="#t236">236</a></span><span class="t"> <span class="nam">input_str</span> <span class="op">=</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">input_data</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
319
+ <p class="mis show_mis"><span class="n"><a id="t237" href="#t237">237</a></span><span class="t"> <span class="key">if</span> <span class="nam">input_str</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
320
+ <p class="mis show_mis"><span class="n"><a id="t238" href="#t238">238</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.input"</span><span class="op">,</span> <span class="nam">input_str</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
321
+ <p class="pln"><span class="n"><a id="t239" href="#t239">239</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
322
+ <p class="pln"><span class="n"><a id="t240" href="#t240">240</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
323
+ <p class="mis show_mis"><span class="n"><a id="t241" href="#t241">241</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
324
+ <p class="mis show_mis"><span class="n"><a id="t242" href="#t242">242</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
325
+ <p class="pln"><span class="n"><a id="t243" href="#t243">243</a></span><span class="t"> <span class="com"># Only extract known MCP context attributes</span>&nbsp;</span><span class="r"></span></p>
326
+ <p class="mis show_mis"><span class="n"><a id="t244" href="#t244">244</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span>&nbsp;</span><span class="r"></span></p>
327
+ <p class="pln"><span class="n"><a id="t245" href="#t245">245</a></span><span class="t"> <span class="str">"request_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
328
+ <p class="pln"><span class="n"><a id="t246" href="#t246">246</a></span><span class="t"> <span class="str">"session_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
329
+ <p class="pln"><span class="n"><a id="t247" href="#t247">247</a></span><span class="t"> <span class="str">"client_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
330
+ <p class="pln"><span class="n"><a id="t248" href="#t248">248</a></span><span class="t"> <span class="str">"user_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
331
+ <p class="pln"><span class="n"><a id="t249" href="#t249">249</a></span><span class="t"> <span class="str">"tenant_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
332
+ <p class="pln"><span class="n"><a id="t250" href="#t250">250</a></span><span class="t"> <span class="op">]</span>&nbsp;</span><span class="r"></span></p>
333
+ <p class="mis show_mis"><span class="n"><a id="t251" href="#t251">251</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
334
+ <p class="mis show_mis"><span class="n"><a id="t252" href="#t252">252</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
335
+ <p class="mis show_mis"><span class="n"><a id="t253" href="#t253">253</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
336
+ <p class="mis show_mis"><span class="n"><a id="t254" href="#t254">254</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
337
+ <p class="mis show_mis"><span class="n"><a id="t255" href="#t255">255</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
338
+ <p class="pln"><span class="n"><a id="t256" href="#t256">256</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
339
+ <p class="pln"><span class="n"><a id="t257" href="#t257">257</a></span><span class="t"> <span class="com"># Also check baggage for session ID</span>&nbsp;</span><span class="r"></span></p>
340
+ <p class="mis show_mis"><span class="n"><a id="t258" href="#t258">258</a></span><span class="t"> <span class="nam">session_id_from_baggage</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">get_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
341
+ <p class="mis show_mis"><span class="n"><a id="t259" href="#t259">259</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id_from_baggage</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
342
+ <p class="mis show_mis"><span class="n"><a id="t260" href="#t260">260</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id_from_baggage</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
343
+ <p class="pln"><span class="n"><a id="t261" href="#t261">261</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
344
+ <p class="pln"><span class="n"><a id="t262" href="#t262">262</a></span><span class="t"> <span class="com"># Add event for tool execution start</span>&nbsp;</span><span class="r"></span></p>
345
+ <p class="mis show_mis"><span class="n"><a id="t263" href="#t263">263</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"tool.execution.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"tool.name"</span><span class="op">:</span> <span class="nam">tool_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
346
+ <p class="pln"><span class="n"><a id="t264" href="#t264">264</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
347
+ <p class="mis show_mis"><span class="n"><a id="t265" href="#t265">265</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
348
+ <p class="mis show_mis"><span class="n"><a id="t266" href="#t266">266</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
349
+ <p class="mis show_mis"><span class="n"><a id="t267" href="#t267">267</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
350
+ <p class="pln"><span class="n"><a id="t268" href="#t268">268</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
351
+ <p class="pln"><span class="n"><a id="t269" href="#t269">269</a></span><span class="t"> <span class="com"># Add event for successful completion</span>&nbsp;</span><span class="r"></span></p>
352
+ <p class="mis show_mis"><span class="n"><a id="t270" href="#t270">270</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"tool.execution.completed"</span><span class="op">,</span> <span class="op">{</span><span class="str">"tool.name"</span><span class="op">:</span> <span class="nam">tool_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
353
+ <p class="pln"><span class="n"><a id="t271" href="#t271">271</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
354
+ <p class="pln"><span class="n"><a id="t272" href="#t272">272</a></span><span class="t"> <span class="com"># Record metrics for successful execution</span>&nbsp;</span><span class="r"></span></p>
355
+ <p class="mis show_mis"><span class="n"><a id="t273" href="#t273">273</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
356
+ <p class="mis show_mis"><span class="n"><a id="t274" href="#t274">274</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
357
+ <p class="pln"><span class="n"><a id="t275" href="#t275">275</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
358
+ <p class="mis show_mis"><span class="n"><a id="t276" href="#t276">276</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
359
+ <p class="mis show_mis"><span class="n"><a id="t277" href="#t277">277</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_tool_execution</span><span class="op">(</span><span class="nam">tool_name</span><span class="op">,</span> <span class="str">"success"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
360
+ <p class="mis show_mis"><span class="n"><a id="t278" href="#t278">278</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_tool_duration</span><span class="op">(</span><span class="nam">tool_name</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
361
+ <p class="mis show_mis"><span class="n"><a id="t279" href="#t279">279</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
362
+ <p class="pln"><span class="n"><a id="t280" href="#t280">280</a></span><span class="t"> <span class="com"># Metrics not available, continue without metrics</span>&nbsp;</span><span class="r"></span></p>
363
+ <p class="mis show_mis"><span class="n"><a id="t281" href="#t281">281</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
364
+ <p class="pln"><span class="n"><a id="t282" href="#t282">282</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
365
+ <p class="pln"><span class="n"><a id="t283" href="#t283">283</a></span><span class="t"> <span class="com"># Capture result metadata</span>&nbsp;</span><span class="r"></span></p>
366
+ <p class="mis show_mis"><span class="n"><a id="t284" href="#t284">284</a></span><span class="t"> <span class="key">if</span> <span class="nam">result</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
367
+ <p class="mis show_mis"><span class="n"><a id="t285" href="#t285">285</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.result.type"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
368
+ <p class="pln"><span class="n"><a id="t286" href="#t286">286</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
369
+ <p class="mis show_mis"><span class="n"><a id="t287" href="#t287">287</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">list</span> <span class="op">|</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">and</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="str">"__len__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
370
+ <p class="mis show_mis"><span class="n"><a id="t288" href="#t288">288</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.result.size"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
371
+ <p class="mis show_mis"><span class="n"><a id="t289" href="#t289">289</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
372
+ <p class="mis show_mis"><span class="n"><a id="t290" href="#t290">290</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.result.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
373
+ <p class="pln"><span class="n"><a id="t291" href="#t291">291</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
374
+ <p class="pln"><span class="n"><a id="t292" href="#t292">292</a></span><span class="t"> <span class="com"># Capture full output if detailed tracing is enabled</span>&nbsp;</span><span class="r"></span></p>
375
+ <p class="mis show_mis"><span class="n"><a id="t293" href="#t293">293</a></span><span class="t"> <span class="key">if</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
376
+ <p class="mis show_mis"><span class="n"><a id="t294" href="#t294">294</a></span><span class="t"> <span class="nam">output_str</span> <span class="op">=</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
377
+ <p class="mis show_mis"><span class="n"><a id="t295" href="#t295">295</a></span><span class="t"> <span class="key">if</span> <span class="nam">output_str</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
378
+ <p class="mis show_mis"><span class="n"><a id="t296" href="#t296">296</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.output"</span><span class="op">,</span> <span class="nam">output_str</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
379
+ <p class="pln"><span class="n"><a id="t297" href="#t297">297</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
380
+ <p class="mis show_mis"><span class="n"><a id="t298" href="#t298">298</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
381
+ <p class="mis show_mis"><span class="n"><a id="t299" href="#t299">299</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
382
+ <p class="mis show_mis"><span class="n"><a id="t300" href="#t300">300</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
383
+ <p class="mis show_mis"><span class="n"><a id="t301" href="#t301">301</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
384
+ <p class="pln"><span class="n"><a id="t302" href="#t302">302</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
385
+ <p class="pln"><span class="n"><a id="t303" href="#t303">303</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
386
+ <p class="mis show_mis"><span class="n"><a id="t304" href="#t304">304</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
387
+ <p class="pln"><span class="n"><a id="t305" href="#t305">305</a></span><span class="t"> <span class="str">"tool.execution.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
388
+ <p class="pln"><span class="n"><a id="t306" href="#t306">306</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
389
+ <p class="pln"><span class="n"><a id="t307" href="#t307">307</a></span><span class="t"> <span class="str">"tool.name"</span><span class="op">:</span> <span class="nam">tool_name</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
390
+ <p class="pln"><span class="n"><a id="t308" href="#t308">308</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
391
+ <p class="pln"><span class="n"><a id="t309" href="#t309">309</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
392
+ <p class="pln"><span class="n"><a id="t310" href="#t310">310</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
393
+ <p class="pln"><span class="n"><a id="t311" href="#t311">311</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
394
+ <p class="pln"><span class="n"><a id="t312" href="#t312">312</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
395
+ <p class="pln"><span class="n"><a id="t313" href="#t313">313</a></span><span class="t"> <span class="com"># Record metrics for failed execution</span>&nbsp;</span><span class="r"></span></p>
396
+ <p class="mis show_mis"><span class="n"><a id="t314" href="#t314">314</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
397
+ <p class="mis show_mis"><span class="n"><a id="t315" href="#t315">315</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
398
+ <p class="pln"><span class="n"><a id="t316" href="#t316">316</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
399
+ <p class="mis show_mis"><span class="n"><a id="t317" href="#t317">317</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
400
+ <p class="mis show_mis"><span class="n"><a id="t318" href="#t318">318</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_tool_execution</span><span class="op">(</span><span class="nam">tool_name</span><span class="op">,</span> <span class="str">"error"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
401
+ <p class="mis show_mis"><span class="n"><a id="t319" href="#t319">319</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_error</span><span class="op">(</span><span class="str">"tool"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
402
+ <p class="mis show_mis"><span class="n"><a id="t320" href="#t320">320</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
403
+ <p class="pln"><span class="n"><a id="t321" href="#t321">321</a></span><span class="t"> <span class="com"># Metrics not available, continue without metrics</span>&nbsp;</span><span class="r"></span></p>
404
+ <p class="mis show_mis"><span class="n"><a id="t322" href="#t322">322</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
405
+ <p class="pln"><span class="n"><a id="t323" href="#t323">323</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
406
+ <p class="mis show_mis"><span class="n"><a id="t324" href="#t324">324</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
407
+ <p class="pln"><span class="n"><a id="t325" href="#t325">325</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
408
+ <p class="mis show_mis"><span class="n"><a id="t326" href="#t326">326</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
409
+ <p class="mis show_mis"><span class="n"><a id="t327" href="#t327">327</a></span><span class="t"> <span class="key">def</span> <span class="nam">sync_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
410
+ <p class="pln"><span class="n"><a id="t328" href="#t328">328</a></span><span class="t"> <span class="com"># Record metrics timing</span>&nbsp;</span><span class="r"></span></p>
411
+ <p class="mis show_mis"><span class="n"><a id="t329" href="#t329">329</a></span><span class="t"> <span class="key">import</span> <span class="nam">time</span>&nbsp;</span><span class="r"></span></p>
412
+ <p class="pln"><span class="n"><a id="t330" href="#t330">330</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
413
+ <p class="mis show_mis"><span class="n"><a id="t331" href="#t331">331</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
414
+ <p class="pln"><span class="n"><a id="t332" href="#t332">332</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
415
+ <p class="pln"><span class="n"><a id="t333" href="#t333">333</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
416
+ <p class="mis show_mis"><span class="n"><a id="t334" href="#t334">334</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.tool.{tool_name}.execute"</span>&nbsp;</span><span class="r"></span></p>
417
+ <p class="pln"><span class="n"><a id="t335" href="#t335">335</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
418
+ <p class="pln"><span class="n"><a id="t336" href="#t336">336</a></span><span class="t"> <span class="com"># start_as_current_span automatically uses the current context and manages it</span>&nbsp;</span><span class="r"></span></p>
419
+ <p class="mis show_mis"><span class="n"><a id="t337" href="#t337">337</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
420
+ <p class="pln"><span class="n"><a id="t338" href="#t338">338</a></span><span class="t"> <span class="com"># Add essential attributes only</span>&nbsp;</span><span class="r"></span></p>
421
+ <p class="mis show_mis"><span class="n"><a id="t339" href="#t339">339</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"tool"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
422
+ <p class="mis show_mis"><span class="n"><a id="t340" href="#t340">340</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.name"</span><span class="op">,</span> <span class="nam">tool_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
423
+ <p class="mis show_mis"><span class="n"><a id="t341" href="#t341">341</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
424
+ <p class="pln"><span class="n"><a id="t342" href="#t342">342</a></span><span class="t"> <span class="str">"mcp.tool.module"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
425
+ <p class="pln"><span class="n"><a id="t343" href="#t343">343</a></span><span class="t"> <span class="nam">func</span><span class="op">.</span><span class="nam">__module__</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="str">"__module__"</span><span class="op">)</span> <span class="key">else</span> <span class="str">"unknown"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
426
+ <p class="pln"><span class="n"><a id="t344" href="#t344">344</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
427
+ <p class="pln"><span class="n"><a id="t345" href="#t345">345</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
428
+ <p class="pln"><span class="n"><a id="t346" href="#t346">346</a></span><span class="t"> <span class="com"># Add execution context</span>&nbsp;</span><span class="r"></span></p>
429
+ <p class="mis show_mis"><span class="n"><a id="t347" href="#t347">347</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.execution.args_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">args</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
430
+ <p class="mis show_mis"><span class="n"><a id="t348" href="#t348">348</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.execution.kwargs_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">kwargs</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
431
+ <p class="pln"><span class="n"><a id="t349" href="#t349">349</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
432
+ <p class="pln"><span class="n"><a id="t350" href="#t350">350</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
433
+ <p class="mis show_mis"><span class="n"><a id="t351" href="#t351">351</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
434
+ <p class="mis show_mis"><span class="n"><a id="t352" href="#t352">352</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
435
+ <p class="pln"><span class="n"><a id="t353" href="#t353">353</a></span><span class="t"> <span class="com"># Only extract known MCP context attributes</span>&nbsp;</span><span class="r"></span></p>
436
+ <p class="mis show_mis"><span class="n"><a id="t354" href="#t354">354</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span>&nbsp;</span><span class="r"></span></p>
437
+ <p class="pln"><span class="n"><a id="t355" href="#t355">355</a></span><span class="t"> <span class="str">"request_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
438
+ <p class="pln"><span class="n"><a id="t356" href="#t356">356</a></span><span class="t"> <span class="str">"session_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
439
+ <p class="pln"><span class="n"><a id="t357" href="#t357">357</a></span><span class="t"> <span class="str">"client_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
440
+ <p class="pln"><span class="n"><a id="t358" href="#t358">358</a></span><span class="t"> <span class="str">"user_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
441
+ <p class="pln"><span class="n"><a id="t359" href="#t359">359</a></span><span class="t"> <span class="str">"tenant_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
442
+ <p class="pln"><span class="n"><a id="t360" href="#t360">360</a></span><span class="t"> <span class="op">]</span>&nbsp;</span><span class="r"></span></p>
443
+ <p class="mis show_mis"><span class="n"><a id="t361" href="#t361">361</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
444
+ <p class="mis show_mis"><span class="n"><a id="t362" href="#t362">362</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
445
+ <p class="mis show_mis"><span class="n"><a id="t363" href="#t363">363</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
446
+ <p class="mis show_mis"><span class="n"><a id="t364" href="#t364">364</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
447
+ <p class="mis show_mis"><span class="n"><a id="t365" href="#t365">365</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
448
+ <p class="pln"><span class="n"><a id="t366" href="#t366">366</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
449
+ <p class="pln"><span class="n"><a id="t367" href="#t367">367</a></span><span class="t"> <span class="com"># Also check baggage for session ID</span>&nbsp;</span><span class="r"></span></p>
450
+ <p class="mis show_mis"><span class="n"><a id="t368" href="#t368">368</a></span><span class="t"> <span class="nam">session_id_from_baggage</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">get_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
451
+ <p class="mis show_mis"><span class="n"><a id="t369" href="#t369">369</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id_from_baggage</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
452
+ <p class="mis show_mis"><span class="n"><a id="t370" href="#t370">370</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id_from_baggage</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
453
+ <p class="pln"><span class="n"><a id="t371" href="#t371">371</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
454
+ <p class="pln"><span class="n"><a id="t372" href="#t372">372</a></span><span class="t"> <span class="com"># Add event for tool execution start</span>&nbsp;</span><span class="r"></span></p>
455
+ <p class="mis show_mis"><span class="n"><a id="t373" href="#t373">373</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"tool.execution.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"tool.name"</span><span class="op">:</span> <span class="nam">tool_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
456
+ <p class="pln"><span class="n"><a id="t374" href="#t374">374</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
457
+ <p class="mis show_mis"><span class="n"><a id="t375" href="#t375">375</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
458
+ <p class="mis show_mis"><span class="n"><a id="t376" href="#t376">376</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
459
+ <p class="mis show_mis"><span class="n"><a id="t377" href="#t377">377</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
460
+ <p class="pln"><span class="n"><a id="t378" href="#t378">378</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
461
+ <p class="pln"><span class="n"><a id="t379" href="#t379">379</a></span><span class="t"> <span class="com"># Add event for successful completion</span>&nbsp;</span><span class="r"></span></p>
462
+ <p class="mis show_mis"><span class="n"><a id="t380" href="#t380">380</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"tool.execution.completed"</span><span class="op">,</span> <span class="op">{</span><span class="str">"tool.name"</span><span class="op">:</span> <span class="nam">tool_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
463
+ <p class="pln"><span class="n"><a id="t381" href="#t381">381</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
464
+ <p class="pln"><span class="n"><a id="t382" href="#t382">382</a></span><span class="t"> <span class="com"># Record metrics for successful execution</span>&nbsp;</span><span class="r"></span></p>
465
+ <p class="mis show_mis"><span class="n"><a id="t383" href="#t383">383</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
466
+ <p class="mis show_mis"><span class="n"><a id="t384" href="#t384">384</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
467
+ <p class="pln"><span class="n"><a id="t385" href="#t385">385</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
468
+ <p class="mis show_mis"><span class="n"><a id="t386" href="#t386">386</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
469
+ <p class="mis show_mis"><span class="n"><a id="t387" href="#t387">387</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_tool_execution</span><span class="op">(</span><span class="nam">tool_name</span><span class="op">,</span> <span class="str">"success"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
470
+ <p class="mis show_mis"><span class="n"><a id="t388" href="#t388">388</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_tool_duration</span><span class="op">(</span><span class="nam">tool_name</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
471
+ <p class="mis show_mis"><span class="n"><a id="t389" href="#t389">389</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
472
+ <p class="pln"><span class="n"><a id="t390" href="#t390">390</a></span><span class="t"> <span class="com"># Metrics not available, continue without metrics</span>&nbsp;</span><span class="r"></span></p>
473
+ <p class="mis show_mis"><span class="n"><a id="t391" href="#t391">391</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
474
+ <p class="pln"><span class="n"><a id="t392" href="#t392">392</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
475
+ <p class="pln"><span class="n"><a id="t393" href="#t393">393</a></span><span class="t"> <span class="com"># Capture result metadata</span>&nbsp;</span><span class="r"></span></p>
476
+ <p class="mis show_mis"><span class="n"><a id="t394" href="#t394">394</a></span><span class="t"> <span class="key">if</span> <span class="nam">result</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
477
+ <p class="mis show_mis"><span class="n"><a id="t395" href="#t395">395</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.result.type"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
478
+ <p class="pln"><span class="n"><a id="t396" href="#t396">396</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
479
+ <p class="mis show_mis"><span class="n"><a id="t397" href="#t397">397</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">list</span> <span class="op">|</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">and</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="str">"__len__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
480
+ <p class="mis show_mis"><span class="n"><a id="t398" href="#t398">398</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.result.size"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
481
+ <p class="mis show_mis"><span class="n"><a id="t399" href="#t399">399</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
482
+ <p class="mis show_mis"><span class="n"><a id="t400" href="#t400">400</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.result.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
483
+ <p class="pln"><span class="n"><a id="t401" href="#t401">401</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
484
+ <p class="pln"><span class="n"><a id="t402" href="#t402">402</a></span><span class="t"> <span class="com"># Capture full output if detailed tracing is enabled</span>&nbsp;</span><span class="r"></span></p>
485
+ <p class="mis show_mis"><span class="n"><a id="t403" href="#t403">403</a></span><span class="t"> <span class="key">if</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
486
+ <p class="mis show_mis"><span class="n"><a id="t404" href="#t404">404</a></span><span class="t"> <span class="nam">output_str</span> <span class="op">=</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
487
+ <p class="mis show_mis"><span class="n"><a id="t405" href="#t405">405</a></span><span class="t"> <span class="key">if</span> <span class="nam">output_str</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
488
+ <p class="mis show_mis"><span class="n"><a id="t406" href="#t406">406</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.tool.output"</span><span class="op">,</span> <span class="nam">output_str</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
489
+ <p class="pln"><span class="n"><a id="t407" href="#t407">407</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
490
+ <p class="mis show_mis"><span class="n"><a id="t408" href="#t408">408</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
491
+ <p class="mis show_mis"><span class="n"><a id="t409" href="#t409">409</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
492
+ <p class="mis show_mis"><span class="n"><a id="t410" href="#t410">410</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
493
+ <p class="mis show_mis"><span class="n"><a id="t411" href="#t411">411</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
494
+ <p class="pln"><span class="n"><a id="t412" href="#t412">412</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
495
+ <p class="pln"><span class="n"><a id="t413" href="#t413">413</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
496
+ <p class="mis show_mis"><span class="n"><a id="t414" href="#t414">414</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
497
+ <p class="pln"><span class="n"><a id="t415" href="#t415">415</a></span><span class="t"> <span class="str">"tool.execution.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
498
+ <p class="pln"><span class="n"><a id="t416" href="#t416">416</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
499
+ <p class="pln"><span class="n"><a id="t417" href="#t417">417</a></span><span class="t"> <span class="str">"tool.name"</span><span class="op">:</span> <span class="nam">tool_name</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
500
+ <p class="pln"><span class="n"><a id="t418" href="#t418">418</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
501
+ <p class="pln"><span class="n"><a id="t419" href="#t419">419</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
502
+ <p class="pln"><span class="n"><a id="t420" href="#t420">420</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
503
+ <p class="pln"><span class="n"><a id="t421" href="#t421">421</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
504
+ <p class="pln"><span class="n"><a id="t422" href="#t422">422</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
505
+ <p class="pln"><span class="n"><a id="t423" href="#t423">423</a></span><span class="t"> <span class="com"># Record metrics for failed execution</span>&nbsp;</span><span class="r"></span></p>
506
+ <p class="mis show_mis"><span class="n"><a id="t424" href="#t424">424</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
507
+ <p class="mis show_mis"><span class="n"><a id="t425" href="#t425">425</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
508
+ <p class="pln"><span class="n"><a id="t426" href="#t426">426</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
509
+ <p class="mis show_mis"><span class="n"><a id="t427" href="#t427">427</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
510
+ <p class="mis show_mis"><span class="n"><a id="t428" href="#t428">428</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_tool_execution</span><span class="op">(</span><span class="nam">tool_name</span><span class="op">,</span> <span class="str">"error"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
511
+ <p class="mis show_mis"><span class="n"><a id="t429" href="#t429">429</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_error</span><span class="op">(</span><span class="str">"tool"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
512
+ <p class="mis show_mis"><span class="n"><a id="t430" href="#t430">430</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
513
+ <p class="pln"><span class="n"><a id="t431" href="#t431">431</a></span><span class="t"> <span class="com"># Metrics not available, continue without metrics</span>&nbsp;</span><span class="r"></span></p>
514
+ <p class="mis show_mis"><span class="n"><a id="t432" href="#t432">432</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
515
+ <p class="pln"><span class="n"><a id="t433" href="#t433">433</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
516
+ <p class="mis show_mis"><span class="n"><a id="t434" href="#t434">434</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
517
+ <p class="pln"><span class="n"><a id="t435" href="#t435">435</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
518
+ <p class="pln"><span class="n"><a id="t436" href="#t436">436</a></span><span class="t"> <span class="com"># Return appropriate wrapper based on function type</span>&nbsp;</span><span class="r"></span></p>
519
+ <p class="mis show_mis"><span class="n"><a id="t437" href="#t437">437</a></span><span class="t"> <span class="key">if</span> <span class="nam">asyncio</span><span class="op">.</span><span class="nam">iscoroutinefunction</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
520
+ <p class="mis show_mis"><span class="n"><a id="t438" href="#t438">438</a></span><span class="t"> <span class="key">return</span> <span class="nam">async_wrapper</span>&nbsp;</span><span class="r"></span></p>
521
+ <p class="pln"><span class="n"><a id="t439" href="#t439">439</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
522
+ <p class="mis show_mis"><span class="n"><a id="t440" href="#t440">440</a></span><span class="t"> <span class="key">return</span> <span class="nam">sync_wrapper</span>&nbsp;</span><span class="r"></span></p>
523
+ <p class="pln"><span class="n"><a id="t441" href="#t441">441</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
524
+ <p class="pln"><span class="n"><a id="t442" href="#t442">442</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
525
+ <p class="mis show_mis"><span class="n"><a id="t443" href="#t443">443</a></span><span class="t"><span class="key">def</span> <span class="nam">instrument_resource</span><span class="op">(</span><span class="nam">func</span><span class="op">:</span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">,</span> <span class="nam">resource_uri</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
526
+ <p class="pln"><span class="n"><a id="t444" href="#t444">444</a></span><span class="t"> <span class="str">"""Instrument a resource function with OpenTelemetry tracing."""</span>&nbsp;</span><span class="r"></span></p>
527
+ <p class="pln"><span class="n"><a id="t445" href="#t445">445</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
528
+ <p class="pln"><span class="n"><a id="t446" href="#t446">446</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
529
+ <p class="pln"><span class="n"><a id="t447" href="#t447">447</a></span><span class="t"> <span class="com"># If telemetry is disabled, return the original function</span>&nbsp;</span><span class="r"></span></p>
530
+ <p class="mis show_mis"><span class="n"><a id="t448" href="#t448">448</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
531
+ <p class="mis show_mis"><span class="n"><a id="t449" href="#t449">449</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span>&nbsp;</span><span class="r"></span></p>
532
+ <p class="pln"><span class="n"><a id="t450" href="#t450">450</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
533
+ <p class="mis show_mis"><span class="n"><a id="t451" href="#t451">451</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
534
+ <p class="pln"><span class="n"><a id="t452" href="#t452">452</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
535
+ <p class="pln"><span class="n"><a id="t453" href="#t453">453</a></span><span class="t"> <span class="com"># Determine if this is a template based on URI pattern</span>&nbsp;</span><span class="r"></span></p>
536
+ <p class="mis show_mis"><span class="n"><a id="t454" href="#t454">454</a></span><span class="t"> <span class="nam">is_template</span> <span class="op">=</span> <span class="str">"{"</span> <span class="key">in</span> <span class="nam">resource_uri</span>&nbsp;</span><span class="r"></span></p>
537
+ <p class="pln"><span class="n"><a id="t455" href="#t455">455</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
538
+ <p class="mis show_mis"><span class="n"><a id="t456" href="#t456">456</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
539
+ <p class="mis show_mis"><span class="n"><a id="t457" href="#t457">457</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">async_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
540
+ <p class="pln"><span class="n"><a id="t458" href="#t458">458</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
541
+ <p class="mis show_mis"><span class="n"><a id="t459" href="#t459">459</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.resource.{'template' if is_template else 'static'}.read"</span>&nbsp;</span><span class="r"></span></p>
542
+ <p class="mis show_mis"><span class="n"><a id="t460" href="#t460">460</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
543
+ <p class="pln"><span class="n"><a id="t461" href="#t461">461</a></span><span class="t"> <span class="com"># Add essential attributes only</span>&nbsp;</span><span class="r"></span></p>
544
+ <p class="mis show_mis"><span class="n"><a id="t462" href="#t462">462</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"resource"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
545
+ <p class="mis show_mis"><span class="n"><a id="t463" href="#t463">463</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.uri"</span><span class="op">,</span> <span class="nam">resource_uri</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
546
+ <p class="mis show_mis"><span class="n"><a id="t464" href="#t464">464</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.is_template"</span><span class="op">,</span> <span class="nam">is_template</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
547
+ <p class="mis show_mis"><span class="n"><a id="t465" href="#t465">465</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
548
+ <p class="pln"><span class="n"><a id="t466" href="#t466">466</a></span><span class="t"> <span class="str">"mcp.resource.module"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
549
+ <p class="pln"><span class="n"><a id="t467" href="#t467">467</a></span><span class="t"> <span class="nam">func</span><span class="op">.</span><span class="nam">__module__</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="str">"__module__"</span><span class="op">)</span> <span class="key">else</span> <span class="str">"unknown"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
550
+ <p class="pln"><span class="n"><a id="t468" href="#t468">468</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
551
+ <p class="pln"><span class="n"><a id="t469" href="#t469">469</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
552
+ <p class="pln"><span class="n"><a id="t470" href="#t470">470</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
553
+ <p class="mis show_mis"><span class="n"><a id="t471" href="#t471">471</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
554
+ <p class="mis show_mis"><span class="n"><a id="t472" href="#t472">472</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
555
+ <p class="pln"><span class="n"><a id="t473" href="#t473">473</a></span><span class="t"> <span class="com"># Only extract known MCP context attributes</span>&nbsp;</span><span class="r"></span></p>
556
+ <p class="mis show_mis"><span class="n"><a id="t474" href="#t474">474</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span>&nbsp;</span><span class="r"></span></p>
557
+ <p class="pln"><span class="n"><a id="t475" href="#t475">475</a></span><span class="t"> <span class="str">"request_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
558
+ <p class="pln"><span class="n"><a id="t476" href="#t476">476</a></span><span class="t"> <span class="str">"session_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
559
+ <p class="pln"><span class="n"><a id="t477" href="#t477">477</a></span><span class="t"> <span class="str">"client_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
560
+ <p class="pln"><span class="n"><a id="t478" href="#t478">478</a></span><span class="t"> <span class="str">"user_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
561
+ <p class="pln"><span class="n"><a id="t479" href="#t479">479</a></span><span class="t"> <span class="str">"tenant_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
562
+ <p class="pln"><span class="n"><a id="t480" href="#t480">480</a></span><span class="t"> <span class="op">]</span>&nbsp;</span><span class="r"></span></p>
563
+ <p class="mis show_mis"><span class="n"><a id="t481" href="#t481">481</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
564
+ <p class="mis show_mis"><span class="n"><a id="t482" href="#t482">482</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
565
+ <p class="mis show_mis"><span class="n"><a id="t483" href="#t483">483</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
566
+ <p class="mis show_mis"><span class="n"><a id="t484" href="#t484">484</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
567
+ <p class="mis show_mis"><span class="n"><a id="t485" href="#t485">485</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
568
+ <p class="pln"><span class="n"><a id="t486" href="#t486">486</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
569
+ <p class="pln"><span class="n"><a id="t487" href="#t487">487</a></span><span class="t"> <span class="com"># Also check baggage for session ID</span>&nbsp;</span><span class="r"></span></p>
570
+ <p class="mis show_mis"><span class="n"><a id="t488" href="#t488">488</a></span><span class="t"> <span class="nam">session_id_from_baggage</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">get_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
571
+ <p class="mis show_mis"><span class="n"><a id="t489" href="#t489">489</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id_from_baggage</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
572
+ <p class="mis show_mis"><span class="n"><a id="t490" href="#t490">490</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id_from_baggage</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
573
+ <p class="pln"><span class="n"><a id="t491" href="#t491">491</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
574
+ <p class="pln"><span class="n"><a id="t492" href="#t492">492</a></span><span class="t"> <span class="com"># Add event for resource read start</span>&nbsp;</span><span class="r"></span></p>
575
+ <p class="mis show_mis"><span class="n"><a id="t493" href="#t493">493</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"resource.read.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"resource.uri"</span><span class="op">:</span> <span class="nam">resource_uri</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
576
+ <p class="pln"><span class="n"><a id="t494" href="#t494">494</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
577
+ <p class="mis show_mis"><span class="n"><a id="t495" href="#t495">495</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
578
+ <p class="mis show_mis"><span class="n"><a id="t496" href="#t496">496</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
579
+ <p class="mis show_mis"><span class="n"><a id="t497" href="#t497">497</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
580
+ <p class="pln"><span class="n"><a id="t498" href="#t498">498</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
581
+ <p class="pln"><span class="n"><a id="t499" href="#t499">499</a></span><span class="t"> <span class="com"># Add event for successful read</span>&nbsp;</span><span class="r"></span></p>
582
+ <p class="mis show_mis"><span class="n"><a id="t500" href="#t500">500</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"resource.read.completed"</span><span class="op">,</span> <span class="op">{</span><span class="str">"resource.uri"</span><span class="op">:</span> <span class="nam">resource_uri</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
583
+ <p class="pln"><span class="n"><a id="t501" href="#t501">501</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
584
+ <p class="pln"><span class="n"><a id="t502" href="#t502">502</a></span><span class="t"> <span class="com"># Add result metadata</span>&nbsp;</span><span class="r"></span></p>
585
+ <p class="mis show_mis"><span class="n"><a id="t503" href="#t503">503</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="str">"__len__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
586
+ <p class="mis show_mis"><span class="n"><a id="t504" href="#t504">504</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.size"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
587
+ <p class="pln"><span class="n"><a id="t505" href="#t505">505</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
588
+ <p class="pln"><span class="n"><a id="t506" href="#t506">506</a></span><span class="t"> <span class="com"># Determine content type if possible</span>&nbsp;</span><span class="r"></span></p>
589
+ <p class="mis show_mis"><span class="n"><a id="t507" href="#t507">507</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
590
+ <p class="mis show_mis"><span class="n"><a id="t508" href="#t508">508</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"text"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
591
+ <p class="mis show_mis"><span class="n"><a id="t509" href="#t509">509</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
592
+ <p class="mis show_mis"><span class="n"><a id="t510" href="#t510">510</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">bytes</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
593
+ <p class="mis show_mis"><span class="n"><a id="t511" href="#t511">511</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"binary"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
594
+ <p class="mis show_mis"><span class="n"><a id="t512" href="#t512">512</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.size_bytes"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
595
+ <p class="mis show_mis"><span class="n"><a id="t513" href="#t513">513</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
596
+ <p class="mis show_mis"><span class="n"><a id="t514" href="#t514">514</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"object"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
597
+ <p class="mis show_mis"><span class="n"><a id="t515" href="#t515">515</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.keys_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
598
+ <p class="mis show_mis"><span class="n"><a id="t516" href="#t516">516</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
599
+ <p class="mis show_mis"><span class="n"><a id="t517" href="#t517">517</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"array"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
600
+ <p class="mis show_mis"><span class="n"><a id="t518" href="#t518">518</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.items_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
601
+ <p class="pln"><span class="n"><a id="t519" href="#t519">519</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
602
+ <p class="mis show_mis"><span class="n"><a id="t520" href="#t520">520</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
603
+ <p class="mis show_mis"><span class="n"><a id="t521" href="#t521">521</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
604
+ <p class="mis show_mis"><span class="n"><a id="t522" href="#t522">522</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
605
+ <p class="mis show_mis"><span class="n"><a id="t523" href="#t523">523</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
606
+ <p class="pln"><span class="n"><a id="t524" href="#t524">524</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
607
+ <p class="pln"><span class="n"><a id="t525" href="#t525">525</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
608
+ <p class="mis show_mis"><span class="n"><a id="t526" href="#t526">526</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
609
+ <p class="pln"><span class="n"><a id="t527" href="#t527">527</a></span><span class="t"> <span class="str">"resource.read.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
610
+ <p class="pln"><span class="n"><a id="t528" href="#t528">528</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
611
+ <p class="pln"><span class="n"><a id="t529" href="#t529">529</a></span><span class="t"> <span class="str">"resource.uri"</span><span class="op">:</span> <span class="nam">resource_uri</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
612
+ <p class="pln"><span class="n"><a id="t530" href="#t530">530</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
613
+ <p class="pln"><span class="n"><a id="t531" href="#t531">531</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
614
+ <p class="pln"><span class="n"><a id="t532" href="#t532">532</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
615
+ <p class="pln"><span class="n"><a id="t533" href="#t533">533</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
616
+ <p class="mis show_mis"><span class="n"><a id="t534" href="#t534">534</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
617
+ <p class="pln"><span class="n"><a id="t535" href="#t535">535</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
618
+ <p class="mis show_mis"><span class="n"><a id="t536" href="#t536">536</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
619
+ <p class="mis show_mis"><span class="n"><a id="t537" href="#t537">537</a></span><span class="t"> <span class="key">def</span> <span class="nam">sync_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
620
+ <p class="pln"><span class="n"><a id="t538" href="#t538">538</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
621
+ <p class="mis show_mis"><span class="n"><a id="t539" href="#t539">539</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.resource.{'template' if is_template else 'static'}.read"</span>&nbsp;</span><span class="r"></span></p>
622
+ <p class="mis show_mis"><span class="n"><a id="t540" href="#t540">540</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
623
+ <p class="pln"><span class="n"><a id="t541" href="#t541">541</a></span><span class="t"> <span class="com"># Add essential attributes only</span>&nbsp;</span><span class="r"></span></p>
624
+ <p class="mis show_mis"><span class="n"><a id="t542" href="#t542">542</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"resource"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
625
+ <p class="mis show_mis"><span class="n"><a id="t543" href="#t543">543</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.uri"</span><span class="op">,</span> <span class="nam">resource_uri</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
626
+ <p class="mis show_mis"><span class="n"><a id="t544" href="#t544">544</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.is_template"</span><span class="op">,</span> <span class="nam">is_template</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
627
+ <p class="mis show_mis"><span class="n"><a id="t545" href="#t545">545</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
628
+ <p class="pln"><span class="n"><a id="t546" href="#t546">546</a></span><span class="t"> <span class="str">"mcp.resource.module"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
629
+ <p class="pln"><span class="n"><a id="t547" href="#t547">547</a></span><span class="t"> <span class="nam">func</span><span class="op">.</span><span class="nam">__module__</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="str">"__module__"</span><span class="op">)</span> <span class="key">else</span> <span class="str">"unknown"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
630
+ <p class="pln"><span class="n"><a id="t548" href="#t548">548</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
631
+ <p class="pln"><span class="n"><a id="t549" href="#t549">549</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
632
+ <p class="pln"><span class="n"><a id="t550" href="#t550">550</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
633
+ <p class="mis show_mis"><span class="n"><a id="t551" href="#t551">551</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
634
+ <p class="mis show_mis"><span class="n"><a id="t552" href="#t552">552</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
635
+ <p class="pln"><span class="n"><a id="t553" href="#t553">553</a></span><span class="t"> <span class="com"># Only extract known MCP context attributes</span>&nbsp;</span><span class="r"></span></p>
636
+ <p class="mis show_mis"><span class="n"><a id="t554" href="#t554">554</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span>&nbsp;</span><span class="r"></span></p>
637
+ <p class="pln"><span class="n"><a id="t555" href="#t555">555</a></span><span class="t"> <span class="str">"request_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
638
+ <p class="pln"><span class="n"><a id="t556" href="#t556">556</a></span><span class="t"> <span class="str">"session_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
639
+ <p class="pln"><span class="n"><a id="t557" href="#t557">557</a></span><span class="t"> <span class="str">"client_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
640
+ <p class="pln"><span class="n"><a id="t558" href="#t558">558</a></span><span class="t"> <span class="str">"user_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
641
+ <p class="pln"><span class="n"><a id="t559" href="#t559">559</a></span><span class="t"> <span class="str">"tenant_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
642
+ <p class="pln"><span class="n"><a id="t560" href="#t560">560</a></span><span class="t"> <span class="op">]</span>&nbsp;</span><span class="r"></span></p>
643
+ <p class="mis show_mis"><span class="n"><a id="t561" href="#t561">561</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
644
+ <p class="mis show_mis"><span class="n"><a id="t562" href="#t562">562</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
645
+ <p class="mis show_mis"><span class="n"><a id="t563" href="#t563">563</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
646
+ <p class="mis show_mis"><span class="n"><a id="t564" href="#t564">564</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
647
+ <p class="mis show_mis"><span class="n"><a id="t565" href="#t565">565</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
648
+ <p class="pln"><span class="n"><a id="t566" href="#t566">566</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
649
+ <p class="pln"><span class="n"><a id="t567" href="#t567">567</a></span><span class="t"> <span class="com"># Also check baggage for session ID</span>&nbsp;</span><span class="r"></span></p>
650
+ <p class="mis show_mis"><span class="n"><a id="t568" href="#t568">568</a></span><span class="t"> <span class="nam">session_id_from_baggage</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">get_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
651
+ <p class="mis show_mis"><span class="n"><a id="t569" href="#t569">569</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id_from_baggage</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
652
+ <p class="mis show_mis"><span class="n"><a id="t570" href="#t570">570</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id_from_baggage</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
653
+ <p class="pln"><span class="n"><a id="t571" href="#t571">571</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
654
+ <p class="pln"><span class="n"><a id="t572" href="#t572">572</a></span><span class="t"> <span class="com"># Add event for resource read start</span>&nbsp;</span><span class="r"></span></p>
655
+ <p class="mis show_mis"><span class="n"><a id="t573" href="#t573">573</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"resource.read.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"resource.uri"</span><span class="op">:</span> <span class="nam">resource_uri</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
656
+ <p class="pln"><span class="n"><a id="t574" href="#t574">574</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
657
+ <p class="mis show_mis"><span class="n"><a id="t575" href="#t575">575</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
658
+ <p class="mis show_mis"><span class="n"><a id="t576" href="#t576">576</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
659
+ <p class="mis show_mis"><span class="n"><a id="t577" href="#t577">577</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
660
+ <p class="pln"><span class="n"><a id="t578" href="#t578">578</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
661
+ <p class="pln"><span class="n"><a id="t579" href="#t579">579</a></span><span class="t"> <span class="com"># Add event for successful read</span>&nbsp;</span><span class="r"></span></p>
662
+ <p class="mis show_mis"><span class="n"><a id="t580" href="#t580">580</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"resource.read.completed"</span><span class="op">,</span> <span class="op">{</span><span class="str">"resource.uri"</span><span class="op">:</span> <span class="nam">resource_uri</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
663
+ <p class="pln"><span class="n"><a id="t581" href="#t581">581</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
664
+ <p class="pln"><span class="n"><a id="t582" href="#t582">582</a></span><span class="t"> <span class="com"># Add result metadata</span>&nbsp;</span><span class="r"></span></p>
665
+ <p class="mis show_mis"><span class="n"><a id="t583" href="#t583">583</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="str">"__len__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
666
+ <p class="mis show_mis"><span class="n"><a id="t584" href="#t584">584</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.size"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
667
+ <p class="pln"><span class="n"><a id="t585" href="#t585">585</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
668
+ <p class="pln"><span class="n"><a id="t586" href="#t586">586</a></span><span class="t"> <span class="com"># Determine content type if possible</span>&nbsp;</span><span class="r"></span></p>
669
+ <p class="mis show_mis"><span class="n"><a id="t587" href="#t587">587</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
670
+ <p class="mis show_mis"><span class="n"><a id="t588" href="#t588">588</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"text"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
671
+ <p class="mis show_mis"><span class="n"><a id="t589" href="#t589">589</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
672
+ <p class="mis show_mis"><span class="n"><a id="t590" href="#t590">590</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">bytes</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
673
+ <p class="mis show_mis"><span class="n"><a id="t591" href="#t591">591</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"binary"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
674
+ <p class="mis show_mis"><span class="n"><a id="t592" href="#t592">592</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.size_bytes"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
675
+ <p class="mis show_mis"><span class="n"><a id="t593" href="#t593">593</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
676
+ <p class="mis show_mis"><span class="n"><a id="t594" href="#t594">594</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"object"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
677
+ <p class="mis show_mis"><span class="n"><a id="t595" href="#t595">595</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.keys_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
678
+ <p class="mis show_mis"><span class="n"><a id="t596" href="#t596">596</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
679
+ <p class="mis show_mis"><span class="n"><a id="t597" href="#t597">597</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.type"</span><span class="op">,</span> <span class="str">"array"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
680
+ <p class="mis show_mis"><span class="n"><a id="t598" href="#t598">598</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.resource.result.items_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
681
+ <p class="pln"><span class="n"><a id="t599" href="#t599">599</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
682
+ <p class="mis show_mis"><span class="n"><a id="t600" href="#t600">600</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
683
+ <p class="mis show_mis"><span class="n"><a id="t601" href="#t601">601</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
684
+ <p class="mis show_mis"><span class="n"><a id="t602" href="#t602">602</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
685
+ <p class="mis show_mis"><span class="n"><a id="t603" href="#t603">603</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
686
+ <p class="pln"><span class="n"><a id="t604" href="#t604">604</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
687
+ <p class="pln"><span class="n"><a id="t605" href="#t605">605</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
688
+ <p class="mis show_mis"><span class="n"><a id="t606" href="#t606">606</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
689
+ <p class="pln"><span class="n"><a id="t607" href="#t607">607</a></span><span class="t"> <span class="str">"resource.read.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
690
+ <p class="pln"><span class="n"><a id="t608" href="#t608">608</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
691
+ <p class="pln"><span class="n"><a id="t609" href="#t609">609</a></span><span class="t"> <span class="str">"resource.uri"</span><span class="op">:</span> <span class="nam">resource_uri</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
692
+ <p class="pln"><span class="n"><a id="t610" href="#t610">610</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
693
+ <p class="pln"><span class="n"><a id="t611" href="#t611">611</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
694
+ <p class="pln"><span class="n"><a id="t612" href="#t612">612</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
695
+ <p class="pln"><span class="n"><a id="t613" href="#t613">613</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
696
+ <p class="mis show_mis"><span class="n"><a id="t614" href="#t614">614</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
697
+ <p class="pln"><span class="n"><a id="t615" href="#t615">615</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
698
+ <p class="mis show_mis"><span class="n"><a id="t616" href="#t616">616</a></span><span class="t"> <span class="key">if</span> <span class="nam">asyncio</span><span class="op">.</span><span class="nam">iscoroutinefunction</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
699
+ <p class="mis show_mis"><span class="n"><a id="t617" href="#t617">617</a></span><span class="t"> <span class="key">return</span> <span class="nam">async_wrapper</span>&nbsp;</span><span class="r"></span></p>
700
+ <p class="pln"><span class="n"><a id="t618" href="#t618">618</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
701
+ <p class="mis show_mis"><span class="n"><a id="t619" href="#t619">619</a></span><span class="t"> <span class="key">return</span> <span class="nam">sync_wrapper</span>&nbsp;</span><span class="r"></span></p>
702
+ <p class="pln"><span class="n"><a id="t620" href="#t620">620</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
703
+ <p class="pln"><span class="n"><a id="t621" href="#t621">621</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
704
+ <p class="mis show_mis"><span class="n"><a id="t622" href="#t622">622</a></span><span class="t"><span class="key">def</span> <span class="nam">instrument_elicitation</span><span class="op">(</span><span class="nam">func</span><span class="op">:</span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">,</span> <span class="nam">elicitation_type</span><span class="op">:</span> <span class="nam">str</span> <span class="op">=</span> <span class="str">"elicit"</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
705
+ <p class="pln"><span class="n"><a id="t623" href="#t623">623</a></span><span class="t"> <span class="str">"""Instrument an elicitation function with OpenTelemetry tracing."""</span>&nbsp;</span><span class="r"></span></p>
706
+ <p class="pln"><span class="n"><a id="t624" href="#t624">624</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
707
+ <p class="pln"><span class="n"><a id="t625" href="#t625">625</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
708
+ <p class="pln"><span class="n"><a id="t626" href="#t626">626</a></span><span class="t"> <span class="com"># If telemetry is disabled, return the original function</span>&nbsp;</span><span class="r"></span></p>
709
+ <p class="mis show_mis"><span class="n"><a id="t627" href="#t627">627</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
710
+ <p class="mis show_mis"><span class="n"><a id="t628" href="#t628">628</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span>&nbsp;</span><span class="r"></span></p>
711
+ <p class="pln"><span class="n"><a id="t629" href="#t629">629</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
712
+ <p class="mis show_mis"><span class="n"><a id="t630" href="#t630">630</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
713
+ <p class="pln"><span class="n"><a id="t631" href="#t631">631</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
714
+ <p class="mis show_mis"><span class="n"><a id="t632" href="#t632">632</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
715
+ <p class="mis show_mis"><span class="n"><a id="t633" href="#t633">633</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">async_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
716
+ <p class="pln"><span class="n"><a id="t634" href="#t634">634</a></span><span class="t"> <span class="com"># If telemetry is disabled at runtime, call original function</span>&nbsp;</span><span class="r"></span></p>
717
+ <p class="pln"><span class="n"><a id="t635" href="#t635">635</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
718
+ <p class="mis show_mis"><span class="n"><a id="t636" href="#t636">636</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
719
+ <p class="mis show_mis"><span class="n"><a id="t637" href="#t637">637</a></span><span class="t"> <span class="key">return</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
720
+ <p class="pln"><span class="n"><a id="t638" href="#t638">638</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
721
+ <p class="pln"><span class="n"><a id="t639" href="#t639">639</a></span><span class="t"> <span class="com"># Record metrics timing</span>&nbsp;</span><span class="r"></span></p>
722
+ <p class="mis show_mis"><span class="n"><a id="t640" href="#t640">640</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
723
+ <p class="pln"><span class="n"><a id="t641" href="#t641">641</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
724
+ <p class="pln"><span class="n"><a id="t642" href="#t642">642</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
725
+ <p class="mis show_mis"><span class="n"><a id="t643" href="#t643">643</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.elicitation.{elicitation_type}.request"</span>&nbsp;</span><span class="r"></span></p>
726
+ <p class="mis show_mis"><span class="n"><a id="t644" href="#t644">644</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
727
+ <p class="pln"><span class="n"><a id="t645" href="#t645">645</a></span><span class="t"> <span class="com"># Add essential attributes</span>&nbsp;</span><span class="r"></span></p>
728
+ <p class="mis show_mis"><span class="n"><a id="t646" href="#t646">646</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"elicitation"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
729
+ <p class="mis show_mis"><span class="n"><a id="t647" href="#t647">647</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.type"</span><span class="op">,</span> <span class="nam">elicitation_type</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
730
+ <p class="pln"><span class="n"><a id="t648" href="#t648">648</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
731
+ <p class="pln"><span class="n"><a id="t649" href="#t649">649</a></span><span class="t"> <span class="com"># Capture elicitation parameters if detailed tracing is enabled</span>&nbsp;</span><span class="r"></span></p>
732
+ <p class="mis show_mis"><span class="n"><a id="t650" href="#t650">650</a></span><span class="t"> <span class="key">if</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
733
+ <p class="pln"><span class="n"><a id="t651" href="#t651">651</a></span><span class="t"> <span class="com"># Extract message from first argument (common pattern)</span>&nbsp;</span><span class="r"></span></p>
734
+ <p class="mis show_mis"><span class="n"><a id="t652" href="#t652">652</a></span><span class="t"> <span class="key">if</span> <span class="nam">args</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
735
+ <p class="mis show_mis"><span class="n"><a id="t653" href="#t653">653</a></span><span class="t"> <span class="nam">message</span> <span class="op">=</span> <span class="nam">args</span><span class="op">[</span><span class="num">0</span><span class="op">]</span> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">args</span><span class="op">[</span><span class="num">0</span><span class="op">]</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
736
+ <p class="mis show_mis"><span class="n"><a id="t654" href="#t654">654</a></span><span class="t"> <span class="key">if</span> <span class="nam">message</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
737
+ <p class="mis show_mis"><span class="n"><a id="t655" href="#t655">655</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.message"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">message</span><span class="op">,</span> <span class="num">500</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
738
+ <p class="pln"><span class="n"><a id="t656" href="#t656">656</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
739
+ <p class="pln"><span class="n"><a id="t657" href="#t657">657</a></span><span class="t"> <span class="com"># Extract response_type from kwargs/args</span>&nbsp;</span><span class="r"></span></p>
740
+ <p class="mis show_mis"><span class="n"><a id="t658" href="#t658">658</a></span><span class="t"> <span class="nam">response_type</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"response_type"</span><span class="op">)</span> <span class="key">or</span> <span class="op">(</span><span class="nam">args</span><span class="op">[</span><span class="num">1</span><span class="op">]</span> <span class="key">if</span> <span class="nam">len</span><span class="op">(</span><span class="nam">args</span><span class="op">)</span> <span class="op">></span> <span class="num">1</span> <span class="key">else</span> <span class="key">None</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
741
+ <p class="mis show_mis"><span class="n"><a id="t659" href="#t659">659</a></span><span class="t"> <span class="key">if</span> <span class="nam">response_type</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
742
+ <p class="mis show_mis"><span class="n"><a id="t660" href="#t660">660</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">response_type</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
743
+ <p class="mis show_mis"><span class="n"><a id="t661" href="#t661">661</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.response_type"</span><span class="op">,</span> <span class="str">"choice"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
744
+ <p class="mis show_mis"><span class="n"><a id="t662" href="#t662">662</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.choices"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">response_type</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
745
+ <p class="mis show_mis"><span class="n"><a id="t663" href="#t663">663</a></span><span class="t"> <span class="key">elif</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">response_type</span><span class="op">,</span> <span class="str">"__name__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
746
+ <p class="mis show_mis"><span class="n"><a id="t664" href="#t664">664</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.response_type"</span><span class="op">,</span> <span class="nam">response_type</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
747
+ <p class="pln"><span class="n"><a id="t665" href="#t665">665</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
748
+ <p class="mis show_mis"><span class="n"><a id="t666" href="#t666">666</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.response_type"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">type</span><span class="op">(</span><span class="nam">response_type</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
749
+ <p class="pln"><span class="n"><a id="t667" href="#t667">667</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
750
+ <p class="pln"><span class="n"><a id="t668" href="#t668">668</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
751
+ <p class="mis show_mis"><span class="n"><a id="t669" href="#t669">669</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
752
+ <p class="mis show_mis"><span class="n"><a id="t670" href="#t670">670</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
753
+ <p class="mis show_mis"><span class="n"><a id="t671" href="#t671">671</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span><span class="str">"request_id"</span><span class="op">,</span> <span class="str">"session_id"</span><span class="op">,</span> <span class="str">"client_id"</span><span class="op">,</span> <span class="str">"user_id"</span><span class="op">,</span> <span class="str">"tenant_id"</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
754
+ <p class="mis show_mis"><span class="n"><a id="t672" href="#t672">672</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
755
+ <p class="mis show_mis"><span class="n"><a id="t673" href="#t673">673</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
756
+ <p class="mis show_mis"><span class="n"><a id="t674" href="#t674">674</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
757
+ <p class="mis show_mis"><span class="n"><a id="t675" href="#t675">675</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
758
+ <p class="mis show_mis"><span class="n"><a id="t676" href="#t676">676</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
759
+ <p class="pln"><span class="n"><a id="t677" href="#t677">677</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
760
+ <p class="pln"><span class="n"><a id="t678" href="#t678">678</a></span><span class="t"> <span class="com"># Add event for elicitation start</span>&nbsp;</span><span class="r"></span></p>
761
+ <p class="mis show_mis"><span class="n"><a id="t679" href="#t679">679</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"elicitation.request.started"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
762
+ <p class="pln"><span class="n"><a id="t680" href="#t680">680</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
763
+ <p class="mis show_mis"><span class="n"><a id="t681" href="#t681">681</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
764
+ <p class="mis show_mis"><span class="n"><a id="t682" href="#t682">682</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
765
+ <p class="mis show_mis"><span class="n"><a id="t683" href="#t683">683</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
766
+ <p class="pln"><span class="n"><a id="t684" href="#t684">684</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
767
+ <p class="pln"><span class="n"><a id="t685" href="#t685">685</a></span><span class="t"> <span class="com"># Add event for successful completion</span>&nbsp;</span><span class="r"></span></p>
768
+ <p class="mis show_mis"><span class="n"><a id="t686" href="#t686">686</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"elicitation.request.completed"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
769
+ <p class="pln"><span class="n"><a id="t687" href="#t687">687</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
770
+ <p class="pln"><span class="n"><a id="t688" href="#t688">688</a></span><span class="t"> <span class="com"># Capture result metadata</span>&nbsp;</span><span class="r"></span></p>
771
+ <p class="mis show_mis"><span class="n"><a id="t689" href="#t689">689</a></span><span class="t"> <span class="key">if</span> <span class="nam">result</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span> <span class="key">and</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
772
+ <p class="mis show_mis"><span class="n"><a id="t690" href="#t690">690</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
773
+ <p class="mis show_mis"><span class="n"><a id="t691" href="#t691">691</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.result.content"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="num">500</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
774
+ <p class="mis show_mis"><span class="n"><a id="t692" href="#t692">692</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="op">(</span><span class="nam">list</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span><span class="op">)</span> <span class="key">and</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="str">"__len__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
775
+ <p class="mis show_mis"><span class="n"><a id="t693" href="#t693">693</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.result.size"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
776
+ <p class="mis show_mis"><span class="n"><a id="t694" href="#t694">694</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.result.content"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="num">1000</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
777
+ <p class="pln"><span class="n"><a id="t695" href="#t695">695</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
778
+ <p class="pln"><span class="n"><a id="t696" href="#t696">696</a></span><span class="t"> <span class="com"># Record metrics for successful elicitation</span>&nbsp;</span><span class="r"></span></p>
779
+ <p class="mis show_mis"><span class="n"><a id="t697" href="#t697">697</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
780
+ <p class="mis show_mis"><span class="n"><a id="t698" href="#t698">698</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
781
+ <p class="pln"><span class="n"><a id="t699" href="#t699">699</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
782
+ <p class="mis show_mis"><span class="n"><a id="t700" href="#t700">700</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
783
+ <p class="mis show_mis"><span class="n"><a id="t701" href="#t701">701</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_elicitation</span><span class="op">(</span><span class="nam">elicitation_type</span><span class="op">,</span> <span class="str">"success"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
784
+ <p class="mis show_mis"><span class="n"><a id="t702" href="#t702">702</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_elicitation_duration</span><span class="op">(</span><span class="nam">elicitation_type</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
785
+ <p class="mis show_mis"><span class="n"><a id="t703" href="#t703">703</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
786
+ <p class="mis show_mis"><span class="n"><a id="t704" href="#t704">704</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
787
+ <p class="pln"><span class="n"><a id="t705" href="#t705">705</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
788
+ <p class="mis show_mis"><span class="n"><a id="t706" href="#t706">706</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
789
+ <p class="mis show_mis"><span class="n"><a id="t707" href="#t707">707</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
790
+ <p class="mis show_mis"><span class="n"><a id="t708" href="#t708">708</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
791
+ <p class="mis show_mis"><span class="n"><a id="t709" href="#t709">709</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
792
+ <p class="pln"><span class="n"><a id="t710" href="#t710">710</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
793
+ <p class="pln"><span class="n"><a id="t711" href="#t711">711</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
794
+ <p class="mis show_mis"><span class="n"><a id="t712" href="#t712">712</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
795
+ <p class="pln"><span class="n"><a id="t713" href="#t713">713</a></span><span class="t"> <span class="str">"elicitation.request.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
796
+ <p class="pln"><span class="n"><a id="t714" href="#t714">714</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
797
+ <p class="pln"><span class="n"><a id="t715" href="#t715">715</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
798
+ <p class="pln"><span class="n"><a id="t716" href="#t716">716</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
799
+ <p class="pln"><span class="n"><a id="t717" href="#t717">717</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
800
+ <p class="pln"><span class="n"><a id="t718" href="#t718">718</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
801
+ <p class="pln"><span class="n"><a id="t719" href="#t719">719</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
802
+ <p class="pln"><span class="n"><a id="t720" href="#t720">720</a></span><span class="t"> <span class="com"># Record metrics for failed elicitation</span>&nbsp;</span><span class="r"></span></p>
803
+ <p class="mis show_mis"><span class="n"><a id="t721" href="#t721">721</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
804
+ <p class="mis show_mis"><span class="n"><a id="t722" href="#t722">722</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
805
+ <p class="pln"><span class="n"><a id="t723" href="#t723">723</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
806
+ <p class="mis show_mis"><span class="n"><a id="t724" href="#t724">724</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
807
+ <p class="mis show_mis"><span class="n"><a id="t725" href="#t725">725</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_elicitation</span><span class="op">(</span><span class="nam">elicitation_type</span><span class="op">,</span> <span class="str">"error"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
808
+ <p class="mis show_mis"><span class="n"><a id="t726" href="#t726">726</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_error</span><span class="op">(</span><span class="str">"elicitation"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
809
+ <p class="mis show_mis"><span class="n"><a id="t727" href="#t727">727</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
810
+ <p class="mis show_mis"><span class="n"><a id="t728" href="#t728">728</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
811
+ <p class="pln"><span class="n"><a id="t729" href="#t729">729</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
812
+ <p class="mis show_mis"><span class="n"><a id="t730" href="#t730">730</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
813
+ <p class="pln"><span class="n"><a id="t731" href="#t731">731</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
814
+ <p class="mis show_mis"><span class="n"><a id="t732" href="#t732">732</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
815
+ <p class="mis show_mis"><span class="n"><a id="t733" href="#t733">733</a></span><span class="t"> <span class="key">def</span> <span class="nam">sync_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
816
+ <p class="pln"><span class="n"><a id="t734" href="#t734">734</a></span><span class="t"> <span class="com"># If telemetry is disabled at runtime, call original function</span>&nbsp;</span><span class="r"></span></p>
817
+ <p class="pln"><span class="n"><a id="t735" href="#t735">735</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
818
+ <p class="mis show_mis"><span class="n"><a id="t736" href="#t736">736</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
819
+ <p class="mis show_mis"><span class="n"><a id="t737" href="#t737">737</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
820
+ <p class="pln"><span class="n"><a id="t738" href="#t738">738</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
821
+ <p class="pln"><span class="n"><a id="t739" href="#t739">739</a></span><span class="t"> <span class="com"># Record metrics timing</span>&nbsp;</span><span class="r"></span></p>
822
+ <p class="mis show_mis"><span class="n"><a id="t740" href="#t740">740</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
823
+ <p class="pln"><span class="n"><a id="t741" href="#t741">741</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
824
+ <p class="pln"><span class="n"><a id="t742" href="#t742">742</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
825
+ <p class="mis show_mis"><span class="n"><a id="t743" href="#t743">743</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.elicitation.{elicitation_type}.request"</span>&nbsp;</span><span class="r"></span></p>
826
+ <p class="mis show_mis"><span class="n"><a id="t744" href="#t744">744</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
827
+ <p class="pln"><span class="n"><a id="t745" href="#t745">745</a></span><span class="t"> <span class="com"># Add essential attributes</span>&nbsp;</span><span class="r"></span></p>
828
+ <p class="mis show_mis"><span class="n"><a id="t746" href="#t746">746</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"elicitation"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
829
+ <p class="mis show_mis"><span class="n"><a id="t747" href="#t747">747</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.type"</span><span class="op">,</span> <span class="nam">elicitation_type</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
830
+ <p class="pln"><span class="n"><a id="t748" href="#t748">748</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
831
+ <p class="pln"><span class="n"><a id="t749" href="#t749">749</a></span><span class="t"> <span class="com"># Capture elicitation parameters if detailed tracing is enabled</span>&nbsp;</span><span class="r"></span></p>
832
+ <p class="mis show_mis"><span class="n"><a id="t750" href="#t750">750</a></span><span class="t"> <span class="key">if</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
833
+ <p class="mis show_mis"><span class="n"><a id="t751" href="#t751">751</a></span><span class="t"> <span class="key">if</span> <span class="nam">args</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
834
+ <p class="mis show_mis"><span class="n"><a id="t752" href="#t752">752</a></span><span class="t"> <span class="nam">message</span> <span class="op">=</span> <span class="nam">args</span><span class="op">[</span><span class="num">0</span><span class="op">]</span> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">args</span><span class="op">[</span><span class="num">0</span><span class="op">]</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
835
+ <p class="mis show_mis"><span class="n"><a id="t753" href="#t753">753</a></span><span class="t"> <span class="key">if</span> <span class="nam">message</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
836
+ <p class="mis show_mis"><span class="n"><a id="t754" href="#t754">754</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.elicitation.message"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">message</span><span class="op">,</span> <span class="num">500</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
837
+ <p class="pln"><span class="n"><a id="t755" href="#t755">755</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
838
+ <p class="pln"><span class="n"><a id="t756" href="#t756">756</a></span><span class="t"> <span class="com"># Add event for elicitation start</span>&nbsp;</span><span class="r"></span></p>
839
+ <p class="mis show_mis"><span class="n"><a id="t757" href="#t757">757</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"elicitation.request.started"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
840
+ <p class="pln"><span class="n"><a id="t758" href="#t758">758</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
841
+ <p class="mis show_mis"><span class="n"><a id="t759" href="#t759">759</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
842
+ <p class="mis show_mis"><span class="n"><a id="t760" href="#t760">760</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
843
+ <p class="mis show_mis"><span class="n"><a id="t761" href="#t761">761</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
844
+ <p class="pln"><span class="n"><a id="t762" href="#t762">762</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
845
+ <p class="pln"><span class="n"><a id="t763" href="#t763">763</a></span><span class="t"> <span class="com"># Add event for successful completion</span>&nbsp;</span><span class="r"></span></p>
846
+ <p class="mis show_mis"><span class="n"><a id="t764" href="#t764">764</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"elicitation.request.completed"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
847
+ <p class="pln"><span class="n"><a id="t765" href="#t765">765</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
848
+ <p class="pln"><span class="n"><a id="t766" href="#t766">766</a></span><span class="t"> <span class="com"># Record metrics for successful elicitation</span>&nbsp;</span><span class="r"></span></p>
849
+ <p class="mis show_mis"><span class="n"><a id="t767" href="#t767">767</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
850
+ <p class="mis show_mis"><span class="n"><a id="t768" href="#t768">768</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
851
+ <p class="pln"><span class="n"><a id="t769" href="#t769">769</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
852
+ <p class="mis show_mis"><span class="n"><a id="t770" href="#t770">770</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
853
+ <p class="mis show_mis"><span class="n"><a id="t771" href="#t771">771</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_elicitation</span><span class="op">(</span><span class="nam">elicitation_type</span><span class="op">,</span> <span class="str">"success"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
854
+ <p class="mis show_mis"><span class="n"><a id="t772" href="#t772">772</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_elicitation_duration</span><span class="op">(</span><span class="nam">elicitation_type</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
855
+ <p class="mis show_mis"><span class="n"><a id="t773" href="#t773">773</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
856
+ <p class="mis show_mis"><span class="n"><a id="t774" href="#t774">774</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
857
+ <p class="pln"><span class="n"><a id="t775" href="#t775">775</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
858
+ <p class="mis show_mis"><span class="n"><a id="t776" href="#t776">776</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
859
+ <p class="mis show_mis"><span class="n"><a id="t777" href="#t777">777</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
860
+ <p class="mis show_mis"><span class="n"><a id="t778" href="#t778">778</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
861
+ <p class="mis show_mis"><span class="n"><a id="t779" href="#t779">779</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
862
+ <p class="pln"><span class="n"><a id="t780" href="#t780">780</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
863
+ <p class="pln"><span class="n"><a id="t781" href="#t781">781</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
864
+ <p class="mis show_mis"><span class="n"><a id="t782" href="#t782">782</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
865
+ <p class="pln"><span class="n"><a id="t783" href="#t783">783</a></span><span class="t"> <span class="str">"elicitation.request.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
866
+ <p class="pln"><span class="n"><a id="t784" href="#t784">784</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
867
+ <p class="pln"><span class="n"><a id="t785" href="#t785">785</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
868
+ <p class="pln"><span class="n"><a id="t786" href="#t786">786</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
869
+ <p class="pln"><span class="n"><a id="t787" href="#t787">787</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
870
+ <p class="pln"><span class="n"><a id="t788" href="#t788">788</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
871
+ <p class="pln"><span class="n"><a id="t789" href="#t789">789</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
872
+ <p class="pln"><span class="n"><a id="t790" href="#t790">790</a></span><span class="t"> <span class="com"># Record metrics for failed elicitation</span>&nbsp;</span><span class="r"></span></p>
873
+ <p class="mis show_mis"><span class="n"><a id="t791" href="#t791">791</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
874
+ <p class="mis show_mis"><span class="n"><a id="t792" href="#t792">792</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
875
+ <p class="pln"><span class="n"><a id="t793" href="#t793">793</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
876
+ <p class="mis show_mis"><span class="n"><a id="t794" href="#t794">794</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
877
+ <p class="mis show_mis"><span class="n"><a id="t795" href="#t795">795</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_elicitation</span><span class="op">(</span><span class="nam">elicitation_type</span><span class="op">,</span> <span class="str">"error"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
878
+ <p class="mis show_mis"><span class="n"><a id="t796" href="#t796">796</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_error</span><span class="op">(</span><span class="str">"elicitation"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
879
+ <p class="mis show_mis"><span class="n"><a id="t797" href="#t797">797</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
880
+ <p class="mis show_mis"><span class="n"><a id="t798" href="#t798">798</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
881
+ <p class="pln"><span class="n"><a id="t799" href="#t799">799</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
882
+ <p class="mis show_mis"><span class="n"><a id="t800" href="#t800">800</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
883
+ <p class="pln"><span class="n"><a id="t801" href="#t801">801</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
884
+ <p class="mis show_mis"><span class="n"><a id="t802" href="#t802">802</a></span><span class="t"> <span class="key">if</span> <span class="nam">asyncio</span><span class="op">.</span><span class="nam">iscoroutinefunction</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
885
+ <p class="mis show_mis"><span class="n"><a id="t803" href="#t803">803</a></span><span class="t"> <span class="key">return</span> <span class="nam">async_wrapper</span>&nbsp;</span><span class="r"></span></p>
886
+ <p class="pln"><span class="n"><a id="t804" href="#t804">804</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
887
+ <p class="mis show_mis"><span class="n"><a id="t805" href="#t805">805</a></span><span class="t"> <span class="key">return</span> <span class="nam">sync_wrapper</span>&nbsp;</span><span class="r"></span></p>
888
+ <p class="pln"><span class="n"><a id="t806" href="#t806">806</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
889
+ <p class="pln"><span class="n"><a id="t807" href="#t807">807</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
890
+ <p class="mis show_mis"><span class="n"><a id="t808" href="#t808">808</a></span><span class="t"><span class="key">def</span> <span class="nam">instrument_sampling</span><span class="op">(</span><span class="nam">func</span><span class="op">:</span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">,</span> <span class="nam">sampling_type</span><span class="op">:</span> <span class="nam">str</span> <span class="op">=</span> <span class="str">"sample"</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
891
+ <p class="pln"><span class="n"><a id="t809" href="#t809">809</a></span><span class="t"> <span class="str">"""Instrument a sampling function with OpenTelemetry tracing."""</span>&nbsp;</span><span class="r"></span></p>
892
+ <p class="pln"><span class="n"><a id="t810" href="#t810">810</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
893
+ <p class="pln"><span class="n"><a id="t811" href="#t811">811</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
894
+ <p class="pln"><span class="n"><a id="t812" href="#t812">812</a></span><span class="t"> <span class="com"># If telemetry is disabled, return the original function</span>&nbsp;</span><span class="r"></span></p>
895
+ <p class="mis show_mis"><span class="n"><a id="t813" href="#t813">813</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
896
+ <p class="mis show_mis"><span class="n"><a id="t814" href="#t814">814</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span>&nbsp;</span><span class="r"></span></p>
897
+ <p class="pln"><span class="n"><a id="t815" href="#t815">815</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
898
+ <p class="mis show_mis"><span class="n"><a id="t816" href="#t816">816</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
899
+ <p class="pln"><span class="n"><a id="t817" href="#t817">817</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
900
+ <p class="mis show_mis"><span class="n"><a id="t818" href="#t818">818</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
901
+ <p class="mis show_mis"><span class="n"><a id="t819" href="#t819">819</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">async_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
902
+ <p class="pln"><span class="n"><a id="t820" href="#t820">820</a></span><span class="t"> <span class="com"># If telemetry is disabled at runtime, call original function</span>&nbsp;</span><span class="r"></span></p>
903
+ <p class="pln"><span class="n"><a id="t821" href="#t821">821</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
904
+ <p class="mis show_mis"><span class="n"><a id="t822" href="#t822">822</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
905
+ <p class="mis show_mis"><span class="n"><a id="t823" href="#t823">823</a></span><span class="t"> <span class="key">return</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
906
+ <p class="pln"><span class="n"><a id="t824" href="#t824">824</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
907
+ <p class="pln"><span class="n"><a id="t825" href="#t825">825</a></span><span class="t"> <span class="com"># Record metrics timing</span>&nbsp;</span><span class="r"></span></p>
908
+ <p class="mis show_mis"><span class="n"><a id="t826" href="#t826">826</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
909
+ <p class="pln"><span class="n"><a id="t827" href="#t827">827</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
910
+ <p class="pln"><span class="n"><a id="t828" href="#t828">828</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
911
+ <p class="mis show_mis"><span class="n"><a id="t829" href="#t829">829</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.sampling.{sampling_type}.request"</span>&nbsp;</span><span class="r"></span></p>
912
+ <p class="mis show_mis"><span class="n"><a id="t830" href="#t830">830</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
913
+ <p class="pln"><span class="n"><a id="t831" href="#t831">831</a></span><span class="t"> <span class="com"># Add essential attributes</span>&nbsp;</span><span class="r"></span></p>
914
+ <p class="mis show_mis"><span class="n"><a id="t832" href="#t832">832</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"sampling"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
915
+ <p class="mis show_mis"><span class="n"><a id="t833" href="#t833">833</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.type"</span><span class="op">,</span> <span class="nam">sampling_type</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
916
+ <p class="pln"><span class="n"><a id="t834" href="#t834">834</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
917
+ <p class="pln"><span class="n"><a id="t835" href="#t835">835</a></span><span class="t"> <span class="com"># Capture sampling parameters</span>&nbsp;</span><span class="r"></span></p>
918
+ <p class="mis show_mis"><span class="n"><a id="t836" href="#t836">836</a></span><span class="t"> <span class="nam">messages</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"messages"</span><span class="op">)</span> <span class="key">or</span> <span class="op">(</span><span class="nam">args</span><span class="op">[</span><span class="num">0</span><span class="op">]</span> <span class="key">if</span> <span class="nam">args</span> <span class="key">else</span> <span class="key">None</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
919
+ <p class="mis show_mis"><span class="n"><a id="t837" href="#t837">837</a></span><span class="t"> <span class="key">if</span> <span class="nam">messages</span> <span class="key">and</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
920
+ <p class="mis show_mis"><span class="n"><a id="t838" href="#t838">838</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">messages</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
921
+ <p class="mis show_mis"><span class="n"><a id="t839" href="#t839">839</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.messages.content"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">messages</span><span class="op">,</span> <span class="num">1000</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
922
+ <p class="mis show_mis"><span class="n"><a id="t840" href="#t840">840</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">messages</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
923
+ <p class="mis show_mis"><span class="n"><a id="t841" href="#t841">841</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.messages.type"</span><span class="op">,</span> <span class="str">"list"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
924
+ <p class="mis show_mis"><span class="n"><a id="t842" href="#t842">842</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.messages.count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">messages</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
925
+ <p class="mis show_mis"><span class="n"><a id="t843" href="#t843">843</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.messages.content"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">messages</span><span class="op">,</span> <span class="num">1000</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
926
+ <p class="pln"><span class="n"><a id="t844" href="#t844">844</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
927
+ <p class="pln"><span class="n"><a id="t845" href="#t845">845</a></span><span class="t"> <span class="com"># Capture other sampling parameters</span>&nbsp;</span><span class="r"></span></p>
928
+ <p class="mis show_mis"><span class="n"><a id="t846" href="#t846">846</a></span><span class="t"> <span class="nam">system_prompt</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"system_prompt"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
929
+ <p class="mis show_mis"><span class="n"><a id="t847" href="#t847">847</a></span><span class="t"> <span class="key">if</span> <span class="nam">system_prompt</span> <span class="key">and</span> <span class="nam">_detailed_tracing_enabled</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
930
+ <p class="mis show_mis"><span class="n"><a id="t848" href="#t848">848</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.system_prompt.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">str</span><span class="op">(</span><span class="nam">system_prompt</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
931
+ <p class="mis show_mis"><span class="n"><a id="t849" href="#t849">849</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.system_prompt.content"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">system_prompt</span><span class="op">,</span> <span class="num">500</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
932
+ <p class="pln"><span class="n"><a id="t850" href="#t850">850</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
933
+ <p class="mis show_mis"><span class="n"><a id="t851" href="#t851">851</a></span><span class="t"> <span class="nam">temperature</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"temperature"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
934
+ <p class="mis show_mis"><span class="n"><a id="t852" href="#t852">852</a></span><span class="t"> <span class="key">if</span> <span class="nam">temperature</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
935
+ <p class="mis show_mis"><span class="n"><a id="t853" href="#t853">853</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.temperature"</span><span class="op">,</span> <span class="nam">temperature</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
936
+ <p class="pln"><span class="n"><a id="t854" href="#t854">854</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
937
+ <p class="mis show_mis"><span class="n"><a id="t855" href="#t855">855</a></span><span class="t"> <span class="nam">max_tokens</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"max_tokens"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
938
+ <p class="mis show_mis"><span class="n"><a id="t856" href="#t856">856</a></span><span class="t"> <span class="key">if</span> <span class="nam">max_tokens</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
939
+ <p class="mis show_mis"><span class="n"><a id="t857" href="#t857">857</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.max_tokens"</span><span class="op">,</span> <span class="nam">max_tokens</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
940
+ <p class="pln"><span class="n"><a id="t858" href="#t858">858</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
941
+ <p class="mis show_mis"><span class="n"><a id="t859" href="#t859">859</a></span><span class="t"> <span class="nam">model_preferences</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"model_preferences"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
942
+ <p class="mis show_mis"><span class="n"><a id="t860" href="#t860">860</a></span><span class="t"> <span class="key">if</span> <span class="nam">model_preferences</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
943
+ <p class="mis show_mis"><span class="n"><a id="t861" href="#t861">861</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">model_preferences</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
944
+ <p class="mis show_mis"><span class="n"><a id="t862" href="#t862">862</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.model_preferences"</span><span class="op">,</span> <span class="nam">model_preferences</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
945
+ <p class="mis show_mis"><span class="n"><a id="t863" href="#t863">863</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">model_preferences</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
946
+ <p class="mis show_mis"><span class="n"><a id="t864" href="#t864">864</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.model_preferences"</span><span class="op">,</span> <span class="str">","</span><span class="op">.</span><span class="nam">join</span><span class="op">(</span><span class="nam">model_preferences</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
947
+ <p class="pln"><span class="n"><a id="t865" href="#t865">865</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
948
+ <p class="pln"><span class="n"><a id="t866" href="#t866">866</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
949
+ <p class="mis show_mis"><span class="n"><a id="t867" href="#t867">867</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
950
+ <p class="mis show_mis"><span class="n"><a id="t868" href="#t868">868</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
951
+ <p class="mis show_mis"><span class="n"><a id="t869" href="#t869">869</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span><span class="str">"request_id"</span><span class="op">,</span> <span class="str">"session_id"</span><span class="op">,</span> <span class="str">"client_id"</span><span class="op">,</span> <span class="str">"user_id"</span><span class="op">,</span> <span class="str">"tenant_id"</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
952
+ <p class="mis show_mis"><span class="n"><a id="t870" href="#t870">870</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
953
+ <p class="mis show_mis"><span class="n"><a id="t871" href="#t871">871</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
954
+ <p class="mis show_mis"><span class="n"><a id="t872" href="#t872">872</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
955
+ <p class="mis show_mis"><span class="n"><a id="t873" href="#t873">873</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
956
+ <p class="mis show_mis"><span class="n"><a id="t874" href="#t874">874</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
957
+ <p class="pln"><span class="n"><a id="t875" href="#t875">875</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
958
+ <p class="pln"><span class="n"><a id="t876" href="#t876">876</a></span><span class="t"> <span class="com"># Add event for sampling start</span>&nbsp;</span><span class="r"></span></p>
959
+ <p class="mis show_mis"><span class="n"><a id="t877" href="#t877">877</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"sampling.request.started"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
960
+ <p class="pln"><span class="n"><a id="t878" href="#t878">878</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
961
+ <p class="mis show_mis"><span class="n"><a id="t879" href="#t879">879</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
962
+ <p class="mis show_mis"><span class="n"><a id="t880" href="#t880">880</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
963
+ <p class="mis show_mis"><span class="n"><a id="t881" href="#t881">881</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
964
+ <p class="pln"><span class="n"><a id="t882" href="#t882">882</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
965
+ <p class="pln"><span class="n"><a id="t883" href="#t883">883</a></span><span class="t"> <span class="com"># Add event for successful completion</span>&nbsp;</span><span class="r"></span></p>
966
+ <p class="mis show_mis"><span class="n"><a id="t884" href="#t884">884</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"sampling.request.completed"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
967
+ <p class="pln"><span class="n"><a id="t885" href="#t885">885</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
968
+ <p class="pln"><span class="n"><a id="t886" href="#t886">886</a></span><span class="t"> <span class="com"># Capture result metadata</span>&nbsp;</span><span class="r"></span></p>
969
+ <p class="mis show_mis"><span class="n"><a id="t887" href="#t887">887</a></span><span class="t"> <span class="key">if</span> <span class="nam">result</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span> <span class="key">and</span> <span class="nam">_detailed_tracing_enabled</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
970
+ <p class="mis show_mis"><span class="n"><a id="t888" href="#t888">888</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.result.content"</span><span class="op">,</span> <span class="nam">_safe_serialize</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="num">1000</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
971
+ <p class="pln"><span class="n"><a id="t889" href="#t889">889</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
972
+ <p class="pln"><span class="n"><a id="t890" href="#t890">890</a></span><span class="t"> <span class="com"># Record metrics for successful sampling</span>&nbsp;</span><span class="r"></span></p>
973
+ <p class="mis show_mis"><span class="n"><a id="t891" href="#t891">891</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
974
+ <p class="mis show_mis"><span class="n"><a id="t892" href="#t892">892</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
975
+ <p class="pln"><span class="n"><a id="t893" href="#t893">893</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
976
+ <p class="mis show_mis"><span class="n"><a id="t894" href="#t894">894</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
977
+ <p class="mis show_mis"><span class="n"><a id="t895" href="#t895">895</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_sampling</span><span class="op">(</span><span class="nam">sampling_type</span><span class="op">,</span> <span class="str">"success"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
978
+ <p class="mis show_mis"><span class="n"><a id="t896" href="#t896">896</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_sampling_duration</span><span class="op">(</span><span class="nam">sampling_type</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
979
+ <p class="mis show_mis"><span class="n"><a id="t897" href="#t897">897</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
980
+ <p class="mis show_mis"><span class="n"><a id="t898" href="#t898">898</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_sampling_tokens</span><span class="op">(</span><span class="nam">sampling_type</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">.</span><span class="nam">split</span><span class="op">(</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
981
+ <p class="mis show_mis"><span class="n"><a id="t899" href="#t899">899</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
982
+ <p class="mis show_mis"><span class="n"><a id="t900" href="#t900">900</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
983
+ <p class="pln"><span class="n"><a id="t901" href="#t901">901</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
984
+ <p class="mis show_mis"><span class="n"><a id="t902" href="#t902">902</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
985
+ <p class="mis show_mis"><span class="n"><a id="t903" href="#t903">903</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
986
+ <p class="mis show_mis"><span class="n"><a id="t904" href="#t904">904</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
987
+ <p class="mis show_mis"><span class="n"><a id="t905" href="#t905">905</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
988
+ <p class="pln"><span class="n"><a id="t906" href="#t906">906</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
989
+ <p class="pln"><span class="n"><a id="t907" href="#t907">907</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
990
+ <p class="mis show_mis"><span class="n"><a id="t908" href="#t908">908</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
991
+ <p class="pln"><span class="n"><a id="t909" href="#t909">909</a></span><span class="t"> <span class="str">"sampling.request.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
992
+ <p class="pln"><span class="n"><a id="t910" href="#t910">910</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
993
+ <p class="pln"><span class="n"><a id="t911" href="#t911">911</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
994
+ <p class="pln"><span class="n"><a id="t912" href="#t912">912</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
995
+ <p class="pln"><span class="n"><a id="t913" href="#t913">913</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
996
+ <p class="pln"><span class="n"><a id="t914" href="#t914">914</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
997
+ <p class="pln"><span class="n"><a id="t915" href="#t915">915</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
998
+ <p class="pln"><span class="n"><a id="t916" href="#t916">916</a></span><span class="t"> <span class="com"># Record metrics for failed sampling</span>&nbsp;</span><span class="r"></span></p>
999
+ <p class="mis show_mis"><span class="n"><a id="t917" href="#t917">917</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1000
+ <p class="mis show_mis"><span class="n"><a id="t918" href="#t918">918</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
1001
+ <p class="pln"><span class="n"><a id="t919" href="#t919">919</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1002
+ <p class="mis show_mis"><span class="n"><a id="t920" href="#t920">920</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1003
+ <p class="mis show_mis"><span class="n"><a id="t921" href="#t921">921</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_sampling</span><span class="op">(</span><span class="nam">sampling_type</span><span class="op">,</span> <span class="str">"error"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1004
+ <p class="mis show_mis"><span class="n"><a id="t922" href="#t922">922</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_error</span><span class="op">(</span><span class="str">"sampling"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1005
+ <p class="mis show_mis"><span class="n"><a id="t923" href="#t923">923</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1006
+ <p class="mis show_mis"><span class="n"><a id="t924" href="#t924">924</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1007
+ <p class="pln"><span class="n"><a id="t925" href="#t925">925</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1008
+ <p class="mis show_mis"><span class="n"><a id="t926" href="#t926">926</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
1009
+ <p class="pln"><span class="n"><a id="t927" href="#t927">927</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1010
+ <p class="mis show_mis"><span class="n"><a id="t928" href="#t928">928</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1011
+ <p class="mis show_mis"><span class="n"><a id="t929" href="#t929">929</a></span><span class="t"> <span class="key">def</span> <span class="nam">sync_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1012
+ <p class="pln"><span class="n"><a id="t930" href="#t930">930</a></span><span class="t"> <span class="com"># If telemetry is disabled at runtime, call original function</span>&nbsp;</span><span class="r"></span></p>
1013
+ <p class="pln"><span class="n"><a id="t931" href="#t931">931</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
1014
+ <p class="mis show_mis"><span class="n"><a id="t932" href="#t932">932</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1015
+ <p class="mis show_mis"><span class="n"><a id="t933" href="#t933">933</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1016
+ <p class="pln"><span class="n"><a id="t934" href="#t934">934</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1017
+ <p class="pln"><span class="n"><a id="t935" href="#t935">935</a></span><span class="t"> <span class="com"># Record metrics timing</span>&nbsp;</span><span class="r"></span></p>
1018
+ <p class="mis show_mis"><span class="n"><a id="t936" href="#t936">936</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1019
+ <p class="pln"><span class="n"><a id="t937" href="#t937">937</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1020
+ <p class="pln"><span class="n"><a id="t938" href="#t938">938</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
1021
+ <p class="mis show_mis"><span class="n"><a id="t939" href="#t939">939</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.sampling.{sampling_type}.request"</span>&nbsp;</span><span class="r"></span></p>
1022
+ <p class="mis show_mis"><span class="n"><a id="t940" href="#t940">940</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1023
+ <p class="pln"><span class="n"><a id="t941" href="#t941">941</a></span><span class="t"> <span class="com"># Add essential attributes</span>&nbsp;</span><span class="r"></span></p>
1024
+ <p class="mis show_mis"><span class="n"><a id="t942" href="#t942">942</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"sampling"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1025
+ <p class="mis show_mis"><span class="n"><a id="t943" href="#t943">943</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.sampling.type"</span><span class="op">,</span> <span class="nam">sampling_type</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1026
+ <p class="pln"><span class="n"><a id="t944" href="#t944">944</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1027
+ <p class="pln"><span class="n"><a id="t945" href="#t945">945</a></span><span class="t"> <span class="com"># Add event for sampling start</span>&nbsp;</span><span class="r"></span></p>
1028
+ <p class="mis show_mis"><span class="n"><a id="t946" href="#t946">946</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"sampling.request.started"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1029
+ <p class="pln"><span class="n"><a id="t947" href="#t947">947</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1030
+ <p class="mis show_mis"><span class="n"><a id="t948" href="#t948">948</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1031
+ <p class="mis show_mis"><span class="n"><a id="t949" href="#t949">949</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1032
+ <p class="mis show_mis"><span class="n"><a id="t950" href="#t950">950</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1033
+ <p class="pln"><span class="n"><a id="t951" href="#t951">951</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1034
+ <p class="pln"><span class="n"><a id="t952" href="#t952">952</a></span><span class="t"> <span class="com"># Add event for successful completion</span>&nbsp;</span><span class="r"></span></p>
1035
+ <p class="mis show_mis"><span class="n"><a id="t953" href="#t953">953</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"sampling.request.completed"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1036
+ <p class="pln"><span class="n"><a id="t954" href="#t954">954</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1037
+ <p class="pln"><span class="n"><a id="t955" href="#t955">955</a></span><span class="t"> <span class="com"># Record metrics for successful sampling</span>&nbsp;</span><span class="r"></span></p>
1038
+ <p class="mis show_mis"><span class="n"><a id="t956" href="#t956">956</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1039
+ <p class="mis show_mis"><span class="n"><a id="t957" href="#t957">957</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
1040
+ <p class="pln"><span class="n"><a id="t958" href="#t958">958</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1041
+ <p class="mis show_mis"><span class="n"><a id="t959" href="#t959">959</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1042
+ <p class="mis show_mis"><span class="n"><a id="t960" href="#t960">960</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_sampling</span><span class="op">(</span><span class="nam">sampling_type</span><span class="op">,</span> <span class="str">"success"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1043
+ <p class="mis show_mis"><span class="n"><a id="t961" href="#t961">961</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_sampling_duration</span><span class="op">(</span><span class="nam">sampling_type</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1044
+ <p class="mis show_mis"><span class="n"><a id="t962" href="#t962">962</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1045
+ <p class="mis show_mis"><span class="n"><a id="t963" href="#t963">963</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1046
+ <p class="pln"><span class="n"><a id="t964" href="#t964">964</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1047
+ <p class="mis show_mis"><span class="n"><a id="t965" href="#t965">965</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
1048
+ <p class="mis show_mis"><span class="n"><a id="t966" href="#t966">966</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1049
+ <p class="mis show_mis"><span class="n"><a id="t967" href="#t967">967</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1050
+ <p class="mis show_mis"><span class="n"><a id="t968" href="#t968">968</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1051
+ <p class="pln"><span class="n"><a id="t969" href="#t969">969</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1052
+ <p class="pln"><span class="n"><a id="t970" href="#t970">970</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
1053
+ <p class="mis show_mis"><span class="n"><a id="t971" href="#t971">971</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1054
+ <p class="pln"><span class="n"><a id="t972" href="#t972">972</a></span><span class="t"> <span class="str">"sampling.request.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1055
+ <p class="pln"><span class="n"><a id="t973" href="#t973">973</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
1056
+ <p class="pln"><span class="n"><a id="t974" href="#t974">974</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1057
+ <p class="pln"><span class="n"><a id="t975" href="#t975">975</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1058
+ <p class="pln"><span class="n"><a id="t976" href="#t976">976</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1059
+ <p class="pln"><span class="n"><a id="t977" href="#t977">977</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1060
+ <p class="mis show_mis"><span class="n"><a id="t978" href="#t978">978</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
1061
+ <p class="pln"><span class="n"><a id="t979" href="#t979">979</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1062
+ <p class="mis show_mis"><span class="n"><a id="t980" href="#t980">980</a></span><span class="t"> <span class="key">if</span> <span class="nam">asyncio</span><span class="op">.</span><span class="nam">iscoroutinefunction</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1063
+ <p class="mis show_mis"><span class="n"><a id="t981" href="#t981">981</a></span><span class="t"> <span class="key">return</span> <span class="nam">async_wrapper</span>&nbsp;</span><span class="r"></span></p>
1064
+ <p class="pln"><span class="n"><a id="t982" href="#t982">982</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1065
+ <p class="mis show_mis"><span class="n"><a id="t983" href="#t983">983</a></span><span class="t"> <span class="key">return</span> <span class="nam">sync_wrapper</span>&nbsp;</span><span class="r"></span></p>
1066
+ <p class="pln"><span class="n"><a id="t984" href="#t984">984</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1067
+ <p class="pln"><span class="n"><a id="t985" href="#t985">985</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1068
+ <p class="mis show_mis"><span class="n"><a id="t986" href="#t986">986</a></span><span class="t"><span class="key">def</span> <span class="nam">instrument_prompt</span><span class="op">(</span><span class="nam">func</span><span class="op">:</span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">,</span> <span class="nam">prompt_name</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">T</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1069
+ <p class="pln"><span class="n"><a id="t987" href="#t987">987</a></span><span class="t"> <span class="str">"""Instrument a prompt function with OpenTelemetry tracing."""</span>&nbsp;</span><span class="r"></span></p>
1070
+ <p class="pln"><span class="n"><a id="t988" href="#t988">988</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
1071
+ <p class="pln"><span class="n"><a id="t989" href="#t989">989</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1072
+ <p class="pln"><span class="n"><a id="t990" href="#t990">990</a></span><span class="t"> <span class="com"># If telemetry is disabled, return the original function</span>&nbsp;</span><span class="r"></span></p>
1073
+ <p class="mis show_mis"><span class="n"><a id="t991" href="#t991">991</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1074
+ <p class="mis show_mis"><span class="n"><a id="t992" href="#t992">992</a></span><span class="t"> <span class="key">return</span> <span class="nam">func</span>&nbsp;</span><span class="r"></span></p>
1075
+ <p class="pln"><span class="n"><a id="t993" href="#t993">993</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1076
+ <p class="mis show_mis"><span class="n"><a id="t994" href="#t994">994</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1077
+ <p class="pln"><span class="n"><a id="t995" href="#t995">995</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1078
+ <p class="mis show_mis"><span class="n"><a id="t996" href="#t996">996</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1079
+ <p class="mis show_mis"><span class="n"><a id="t997" href="#t997">997</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">async_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1080
+ <p class="pln"><span class="n"><a id="t998" href="#t998">998</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
1081
+ <p class="mis show_mis"><span class="n"><a id="t999" href="#t999">999</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.prompt.{prompt_name}.generate"</span>&nbsp;</span><span class="r"></span></p>
1082
+ <p class="mis show_mis"><span class="n"><a id="t1000" href="#t1000">1000</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1083
+ <p class="pln"><span class="n"><a id="t1001" href="#t1001">1001</a></span><span class="t"> <span class="com"># Add essential attributes only</span>&nbsp;</span><span class="r"></span></p>
1084
+ <p class="mis show_mis"><span class="n"><a id="t1002" href="#t1002">1002</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"prompt"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1085
+ <p class="mis show_mis"><span class="n"><a id="t1003" href="#t1003">1003</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.name"</span><span class="op">,</span> <span class="nam">prompt_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1086
+ <p class="mis show_mis"><span class="n"><a id="t1004" href="#t1004">1004</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1087
+ <p class="pln"><span class="n"><a id="t1005" href="#t1005">1005</a></span><span class="t"> <span class="str">"mcp.prompt.module"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1088
+ <p class="pln"><span class="n"><a id="t1006" href="#t1006">1006</a></span><span class="t"> <span class="nam">func</span><span class="op">.</span><span class="nam">__module__</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="str">"__module__"</span><span class="op">)</span> <span class="key">else</span> <span class="str">"unknown"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1089
+ <p class="pln"><span class="n"><a id="t1007" href="#t1007">1007</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1090
+ <p class="pln"><span class="n"><a id="t1008" href="#t1008">1008</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1091
+ <p class="pln"><span class="n"><a id="t1009" href="#t1009">1009</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
1092
+ <p class="mis show_mis"><span class="n"><a id="t1010" href="#t1010">1010</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1093
+ <p class="mis show_mis"><span class="n"><a id="t1011" href="#t1011">1011</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1094
+ <p class="pln"><span class="n"><a id="t1012" href="#t1012">1012</a></span><span class="t"> <span class="com"># Only extract known MCP context attributes</span>&nbsp;</span><span class="r"></span></p>
1095
+ <p class="mis show_mis"><span class="n"><a id="t1013" href="#t1013">1013</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span>&nbsp;</span><span class="r"></span></p>
1096
+ <p class="pln"><span class="n"><a id="t1014" href="#t1014">1014</a></span><span class="t"> <span class="str">"request_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1097
+ <p class="pln"><span class="n"><a id="t1015" href="#t1015">1015</a></span><span class="t"> <span class="str">"session_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1098
+ <p class="pln"><span class="n"><a id="t1016" href="#t1016">1016</a></span><span class="t"> <span class="str">"client_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1099
+ <p class="pln"><span class="n"><a id="t1017" href="#t1017">1017</a></span><span class="t"> <span class="str">"user_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1100
+ <p class="pln"><span class="n"><a id="t1018" href="#t1018">1018</a></span><span class="t"> <span class="str">"tenant_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1101
+ <p class="pln"><span class="n"><a id="t1019" href="#t1019">1019</a></span><span class="t"> <span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1102
+ <p class="mis show_mis"><span class="n"><a id="t1020" href="#t1020">1020</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1103
+ <p class="mis show_mis"><span class="n"><a id="t1021" href="#t1021">1021</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1104
+ <p class="mis show_mis"><span class="n"><a id="t1022" href="#t1022">1022</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1105
+ <p class="mis show_mis"><span class="n"><a id="t1023" href="#t1023">1023</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1106
+ <p class="mis show_mis"><span class="n"><a id="t1024" href="#t1024">1024</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1107
+ <p class="pln"><span class="n"><a id="t1025" href="#t1025">1025</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1108
+ <p class="pln"><span class="n"><a id="t1026" href="#t1026">1026</a></span><span class="t"> <span class="com"># Also check baggage for session ID</span>&nbsp;</span><span class="r"></span></p>
1109
+ <p class="mis show_mis"><span class="n"><a id="t1027" href="#t1027">1027</a></span><span class="t"> <span class="nam">session_id_from_baggage</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">get_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1110
+ <p class="mis show_mis"><span class="n"><a id="t1028" href="#t1028">1028</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id_from_baggage</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1111
+ <p class="mis show_mis"><span class="n"><a id="t1029" href="#t1029">1029</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id_from_baggage</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1112
+ <p class="pln"><span class="n"><a id="t1030" href="#t1030">1030</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1113
+ <p class="pln"><span class="n"><a id="t1031" href="#t1031">1031</a></span><span class="t"> <span class="com"># Add event for prompt generation start</span>&nbsp;</span><span class="r"></span></p>
1114
+ <p class="mis show_mis"><span class="n"><a id="t1032" href="#t1032">1032</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"prompt.generation.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"prompt.name"</span><span class="op">:</span> <span class="nam">prompt_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1115
+ <p class="pln"><span class="n"><a id="t1033" href="#t1033">1033</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1116
+ <p class="mis show_mis"><span class="n"><a id="t1034" href="#t1034">1034</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1117
+ <p class="mis show_mis"><span class="n"><a id="t1035" href="#t1035">1035</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="key">await</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1118
+ <p class="mis show_mis"><span class="n"><a id="t1036" href="#t1036">1036</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1119
+ <p class="pln"><span class="n"><a id="t1037" href="#t1037">1037</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1120
+ <p class="pln"><span class="n"><a id="t1038" href="#t1038">1038</a></span><span class="t"> <span class="com"># Add event for successful generation</span>&nbsp;</span><span class="r"></span></p>
1121
+ <p class="mis show_mis"><span class="n"><a id="t1039" href="#t1039">1039</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"prompt.generation.completed"</span><span class="op">,</span> <span class="op">{</span><span class="str">"prompt.name"</span><span class="op">:</span> <span class="nam">prompt_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1122
+ <p class="pln"><span class="n"><a id="t1040" href="#t1040">1040</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1123
+ <p class="pln"><span class="n"><a id="t1041" href="#t1041">1041</a></span><span class="t"> <span class="com"># Add message count and type information</span>&nbsp;</span><span class="r"></span></p>
1124
+ <p class="mis show_mis"><span class="n"><a id="t1042" href="#t1042">1042</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1125
+ <p class="mis show_mis"><span class="n"><a id="t1043" href="#t1043">1043</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.message_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1126
+ <p class="mis show_mis"><span class="n"><a id="t1044" href="#t1044">1044</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.type"</span><span class="op">,</span> <span class="str">"message_list"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1127
+ <p class="pln"><span class="n"><a id="t1045" href="#t1045">1045</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1128
+ <p class="pln"><span class="n"><a id="t1046" href="#t1046">1046</a></span><span class="t"> <span class="com"># Analyze message types if they have role attributes</span>&nbsp;</span><span class="r"></span></p>
1129
+ <p class="mis show_mis"><span class="n"><a id="t1047" href="#t1047">1047</a></span><span class="t"> <span class="nam">roles</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1130
+ <p class="mis show_mis"><span class="n"><a id="t1048" href="#t1048">1048</a></span><span class="t"> <span class="key">for</span> <span class="nam">msg</span> <span class="key">in</span> <span class="nam">result</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1131
+ <p class="mis show_mis"><span class="n"><a id="t1049" href="#t1049">1049</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">msg</span><span class="op">,</span> <span class="str">"role"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1132
+ <p class="mis show_mis"><span class="n"><a id="t1050" href="#t1050">1050</a></span><span class="t"> <span class="nam">roles</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">msg</span><span class="op">.</span><span class="nam">role</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1133
+ <p class="mis show_mis"><span class="n"><a id="t1051" href="#t1051">1051</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">msg</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">and</span> <span class="str">"role"</span> <span class="key">in</span> <span class="nam">msg</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1134
+ <p class="mis show_mis"><span class="n"><a id="t1052" href="#t1052">1052</a></span><span class="t"> <span class="nam">roles</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">msg</span><span class="op">[</span><span class="str">"role"</span><span class="op">]</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1135
+ <p class="pln"><span class="n"><a id="t1053" href="#t1053">1053</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1136
+ <p class="mis show_mis"><span class="n"><a id="t1054" href="#t1054">1054</a></span><span class="t"> <span class="key">if</span> <span class="nam">roles</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1137
+ <p class="mis show_mis"><span class="n"><a id="t1055" href="#t1055">1055</a></span><span class="t"> <span class="nam">unique_roles</span> <span class="op">=</span> <span class="nam">list</span><span class="op">(</span><span class="nam">set</span><span class="op">(</span><span class="nam">roles</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1138
+ <p class="mis show_mis"><span class="n"><a id="t1056" href="#t1056">1056</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.roles"</span><span class="op">,</span> <span class="str">","</span><span class="op">.</span><span class="nam">join</span><span class="op">(</span><span class="nam">unique_roles</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1139
+ <p class="mis show_mis"><span class="n"><a id="t1057" href="#t1057">1057</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1140
+ <p class="pln"><span class="n"><a id="t1058" href="#t1058">1058</a></span><span class="t"> <span class="str">"mcp.prompt.result.role_counts"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1141
+ <p class="pln"><span class="n"><a id="t1059" href="#t1059">1059</a></span><span class="t"> <span class="nam">str</span><span class="op">(</span><span class="op">{</span><span class="nam">role</span><span class="op">:</span> <span class="nam">roles</span><span class="op">.</span><span class="nam">count</span><span class="op">(</span><span class="nam">role</span><span class="op">)</span> <span class="key">for</span> <span class="nam">role</span> <span class="key">in</span> <span class="nam">unique_roles</span><span class="op">}</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1142
+ <p class="pln"><span class="n"><a id="t1060" href="#t1060">1060</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1143
+ <p class="mis show_mis"><span class="n"><a id="t1061" href="#t1061">1061</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1144
+ <p class="mis show_mis"><span class="n"><a id="t1062" href="#t1062">1062</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.type"</span><span class="op">,</span> <span class="str">"string"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1145
+ <p class="mis show_mis"><span class="n"><a id="t1063" href="#t1063">1063</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1146
+ <p class="pln"><span class="n"><a id="t1064" href="#t1064">1064</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1147
+ <p class="mis show_mis"><span class="n"><a id="t1065" href="#t1065">1065</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.type"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1148
+ <p class="pln"><span class="n"><a id="t1066" href="#t1066">1066</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1149
+ <p class="mis show_mis"><span class="n"><a id="t1067" href="#t1067">1067</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
1150
+ <p class="mis show_mis"><span class="n"><a id="t1068" href="#t1068">1068</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1151
+ <p class="mis show_mis"><span class="n"><a id="t1069" href="#t1069">1069</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1152
+ <p class="mis show_mis"><span class="n"><a id="t1070" href="#t1070">1070</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1153
+ <p class="pln"><span class="n"><a id="t1071" href="#t1071">1071</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1154
+ <p class="pln"><span class="n"><a id="t1072" href="#t1072">1072</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
1155
+ <p class="mis show_mis"><span class="n"><a id="t1073" href="#t1073">1073</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1156
+ <p class="pln"><span class="n"><a id="t1074" href="#t1074">1074</a></span><span class="t"> <span class="str">"prompt.generation.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1157
+ <p class="pln"><span class="n"><a id="t1075" href="#t1075">1075</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
1158
+ <p class="pln"><span class="n"><a id="t1076" href="#t1076">1076</a></span><span class="t"> <span class="str">"prompt.name"</span><span class="op">:</span> <span class="nam">prompt_name</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1159
+ <p class="pln"><span class="n"><a id="t1077" href="#t1077">1077</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1160
+ <p class="pln"><span class="n"><a id="t1078" href="#t1078">1078</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1161
+ <p class="pln"><span class="n"><a id="t1079" href="#t1079">1079</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1162
+ <p class="pln"><span class="n"><a id="t1080" href="#t1080">1080</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1163
+ <p class="mis show_mis"><span class="n"><a id="t1081" href="#t1081">1081</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
1164
+ <p class="pln"><span class="n"><a id="t1082" href="#t1082">1082</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1165
+ <p class="mis show_mis"><span class="n"><a id="t1083" href="#t1083">1083</a></span><span class="t"> <span class="op">@</span><span class="nam">functools</span><span class="op">.</span><span class="nam">wraps</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1166
+ <p class="mis show_mis"><span class="n"><a id="t1084" href="#t1084">1084</a></span><span class="t"> <span class="key">def</span> <span class="nam">sync_wrapper</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1167
+ <p class="pln"><span class="n"><a id="t1085" href="#t1085">1085</a></span><span class="t"> <span class="com"># Create a more descriptive span name</span>&nbsp;</span><span class="r"></span></p>
1168
+ <p class="mis show_mis"><span class="n"><a id="t1086" href="#t1086">1086</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"mcp.prompt.{prompt_name}.generate"</span>&nbsp;</span><span class="r"></span></p>
1169
+ <p class="mis show_mis"><span class="n"><a id="t1087" href="#t1087">1087</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1170
+ <p class="pln"><span class="n"><a id="t1088" href="#t1088">1088</a></span><span class="t"> <span class="com"># Add essential attributes only</span>&nbsp;</span><span class="r"></span></p>
1171
+ <p class="mis show_mis"><span class="n"><a id="t1089" href="#t1089">1089</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.component.type"</span><span class="op">,</span> <span class="str">"prompt"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1172
+ <p class="mis show_mis"><span class="n"><a id="t1090" href="#t1090">1090</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.name"</span><span class="op">,</span> <span class="nam">prompt_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1173
+ <p class="mis show_mis"><span class="n"><a id="t1091" href="#t1091">1091</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1174
+ <p class="pln"><span class="n"><a id="t1092" href="#t1092">1092</a></span><span class="t"> <span class="str">"mcp.prompt.module"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1175
+ <p class="pln"><span class="n"><a id="t1093" href="#t1093">1093</a></span><span class="t"> <span class="nam">func</span><span class="op">.</span><span class="nam">__module__</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="str">"__module__"</span><span class="op">)</span> <span class="key">else</span> <span class="str">"unknown"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1176
+ <p class="pln"><span class="n"><a id="t1094" href="#t1094">1094</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1177
+ <p class="pln"><span class="n"><a id="t1095" href="#t1095">1095</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1178
+ <p class="pln"><span class="n"><a id="t1096" href="#t1096">1096</a></span><span class="t"> <span class="com"># Extract Context parameter if present</span>&nbsp;</span><span class="r"></span></p>
1179
+ <p class="mis show_mis"><span class="n"><a id="t1097" href="#t1097">1097</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">kwargs</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ctx"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1180
+ <p class="mis show_mis"><span class="n"><a id="t1098" href="#t1098">1098</a></span><span class="t"> <span class="key">if</span> <span class="nam">ctx</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1181
+ <p class="pln"><span class="n"><a id="t1099" href="#t1099">1099</a></span><span class="t"> <span class="com"># Only extract known MCP context attributes</span>&nbsp;</span><span class="r"></span></p>
1182
+ <p class="mis show_mis"><span class="n"><a id="t1100" href="#t1100">1100</a></span><span class="t"> <span class="nam">ctx_attrs</span> <span class="op">=</span> <span class="op">[</span>&nbsp;</span><span class="r"></span></p>
1183
+ <p class="pln"><span class="n"><a id="t1101" href="#t1101">1101</a></span><span class="t"> <span class="str">"request_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1184
+ <p class="pln"><span class="n"><a id="t1102" href="#t1102">1102</a></span><span class="t"> <span class="str">"session_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1185
+ <p class="pln"><span class="n"><a id="t1103" href="#t1103">1103</a></span><span class="t"> <span class="str">"client_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1186
+ <p class="pln"><span class="n"><a id="t1104" href="#t1104">1104</a></span><span class="t"> <span class="str">"user_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1187
+ <p class="pln"><span class="n"><a id="t1105" href="#t1105">1105</a></span><span class="t"> <span class="str">"tenant_id"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1188
+ <p class="pln"><span class="n"><a id="t1106" href="#t1106">1106</a></span><span class="t"> <span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1189
+ <p class="mis show_mis"><span class="n"><a id="t1107" href="#t1107">1107</a></span><span class="t"> <span class="key">for</span> <span class="nam">attr</span> <span class="key">in</span> <span class="nam">ctx_attrs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1190
+ <p class="mis show_mis"><span class="n"><a id="t1108" href="#t1108">1108</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1191
+ <p class="mis show_mis"><span class="n"><a id="t1109" href="#t1109">1109</a></span><span class="t"> <span class="nam">value</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">ctx</span><span class="op">,</span> <span class="nam">attr</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1192
+ <p class="mis show_mis"><span class="n"><a id="t1110" href="#t1110">1110</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span> <span class="key">is</span> <span class="key">not</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1193
+ <p class="mis show_mis"><span class="n"><a id="t1111" href="#t1111">1111</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">f"mcp.context.{attr}"</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">value</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1194
+ <p class="pln"><span class="n"><a id="t1112" href="#t1112">1112</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1195
+ <p class="pln"><span class="n"><a id="t1113" href="#t1113">1113</a></span><span class="t"> <span class="com"># Also check baggage for session ID</span>&nbsp;</span><span class="r"></span></p>
1196
+ <p class="mis show_mis"><span class="n"><a id="t1114" href="#t1114">1114</a></span><span class="t"> <span class="nam">session_id_from_baggage</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">get_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1197
+ <p class="mis show_mis"><span class="n"><a id="t1115" href="#t1115">1115</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id_from_baggage</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1198
+ <p class="mis show_mis"><span class="n"><a id="t1116" href="#t1116">1116</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id_from_baggage</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1199
+ <p class="pln"><span class="n"><a id="t1117" href="#t1117">1117</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1200
+ <p class="pln"><span class="n"><a id="t1118" href="#t1118">1118</a></span><span class="t"> <span class="com"># Add event for prompt generation start</span>&nbsp;</span><span class="r"></span></p>
1201
+ <p class="mis show_mis"><span class="n"><a id="t1119" href="#t1119">1119</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"prompt.generation.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"prompt.name"</span><span class="op">:</span> <span class="nam">prompt_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1202
+ <p class="pln"><span class="n"><a id="t1120" href="#t1120">1120</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1203
+ <p class="mis show_mis"><span class="n"><a id="t1121" href="#t1121">1121</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1204
+ <p class="mis show_mis"><span class="n"><a id="t1122" href="#t1122">1122</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</span> <span class="nam">func</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1205
+ <p class="mis show_mis"><span class="n"><a id="t1123" href="#t1123">1123</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1206
+ <p class="pln"><span class="n"><a id="t1124" href="#t1124">1124</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1207
+ <p class="pln"><span class="n"><a id="t1125" href="#t1125">1125</a></span><span class="t"> <span class="com"># Add event for successful generation</span>&nbsp;</span><span class="r"></span></p>
1208
+ <p class="mis show_mis"><span class="n"><a id="t1126" href="#t1126">1126</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"prompt.generation.completed"</span><span class="op">,</span> <span class="op">{</span><span class="str">"prompt.name"</span><span class="op">:</span> <span class="nam">prompt_name</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1209
+ <p class="pln"><span class="n"><a id="t1127" href="#t1127">1127</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1210
+ <p class="pln"><span class="n"><a id="t1128" href="#t1128">1128</a></span><span class="t"> <span class="com"># Add message count and type information</span>&nbsp;</span><span class="r"></span></p>
1211
+ <p class="mis show_mis"><span class="n"><a id="t1129" href="#t1129">1129</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">list</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1212
+ <p class="mis show_mis"><span class="n"><a id="t1130" href="#t1130">1130</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.message_count"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1213
+ <p class="mis show_mis"><span class="n"><a id="t1131" href="#t1131">1131</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.type"</span><span class="op">,</span> <span class="str">"message_list"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1214
+ <p class="pln"><span class="n"><a id="t1132" href="#t1132">1132</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1215
+ <p class="pln"><span class="n"><a id="t1133" href="#t1133">1133</a></span><span class="t"> <span class="com"># Analyze message types if they have role attributes</span>&nbsp;</span><span class="r"></span></p>
1216
+ <p class="mis show_mis"><span class="n"><a id="t1134" href="#t1134">1134</a></span><span class="t"> <span class="nam">roles</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1217
+ <p class="mis show_mis"><span class="n"><a id="t1135" href="#t1135">1135</a></span><span class="t"> <span class="key">for</span> <span class="nam">msg</span> <span class="key">in</span> <span class="nam">result</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1218
+ <p class="mis show_mis"><span class="n"><a id="t1136" href="#t1136">1136</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">msg</span><span class="op">,</span> <span class="str">"role"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1219
+ <p class="mis show_mis"><span class="n"><a id="t1137" href="#t1137">1137</a></span><span class="t"> <span class="nam">roles</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">msg</span><span class="op">.</span><span class="nam">role</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1220
+ <p class="mis show_mis"><span class="n"><a id="t1138" href="#t1138">1138</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">msg</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">and</span> <span class="str">"role"</span> <span class="key">in</span> <span class="nam">msg</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1221
+ <p class="mis show_mis"><span class="n"><a id="t1139" href="#t1139">1139</a></span><span class="t"> <span class="nam">roles</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">msg</span><span class="op">[</span><span class="str">"role"</span><span class="op">]</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1222
+ <p class="pln"><span class="n"><a id="t1140" href="#t1140">1140</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1223
+ <p class="mis show_mis"><span class="n"><a id="t1141" href="#t1141">1141</a></span><span class="t"> <span class="key">if</span> <span class="nam">roles</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1224
+ <p class="mis show_mis"><span class="n"><a id="t1142" href="#t1142">1142</a></span><span class="t"> <span class="nam">unique_roles</span> <span class="op">=</span> <span class="nam">list</span><span class="op">(</span><span class="nam">set</span><span class="op">(</span><span class="nam">roles</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1225
+ <p class="mis show_mis"><span class="n"><a id="t1143" href="#t1143">1143</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.roles"</span><span class="op">,</span> <span class="str">","</span><span class="op">.</span><span class="nam">join</span><span class="op">(</span><span class="nam">unique_roles</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1226
+ <p class="mis show_mis"><span class="n"><a id="t1144" href="#t1144">1144</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1227
+ <p class="pln"><span class="n"><a id="t1145" href="#t1145">1145</a></span><span class="t"> <span class="str">"mcp.prompt.result.role_counts"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1228
+ <p class="pln"><span class="n"><a id="t1146" href="#t1146">1146</a></span><span class="t"> <span class="nam">str</span><span class="op">(</span><span class="op">{</span><span class="nam">role</span><span class="op">:</span> <span class="nam">roles</span><span class="op">.</span><span class="nam">count</span><span class="op">(</span><span class="nam">role</span><span class="op">)</span> <span class="key">for</span> <span class="nam">role</span> <span class="key">in</span> <span class="nam">unique_roles</span><span class="op">}</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1229
+ <p class="pln"><span class="n"><a id="t1147" href="#t1147">1147</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1230
+ <p class="mis show_mis"><span class="n"><a id="t1148" href="#t1148">1148</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">result</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1231
+ <p class="mis show_mis"><span class="n"><a id="t1149" href="#t1149">1149</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.type"</span><span class="op">,</span> <span class="str">"string"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1232
+ <p class="mis show_mis"><span class="n"><a id="t1150" href="#t1150">1150</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.length"</span><span class="op">,</span> <span class="nam">len</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1233
+ <p class="pln"><span class="n"><a id="t1151" href="#t1151">1151</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1234
+ <p class="mis show_mis"><span class="n"><a id="t1152" href="#t1152">1152</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.prompt.result.type"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">result</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1235
+ <p class="pln"><span class="n"><a id="t1153" href="#t1153">1153</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1236
+ <p class="mis show_mis"><span class="n"><a id="t1154" href="#t1154">1154</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</span>&nbsp;</span><span class="r"></span></p>
1237
+ <p class="mis show_mis"><span class="n"><a id="t1155" href="#t1155">1155</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1238
+ <p class="mis show_mis"><span class="n"><a id="t1156" href="#t1156">1156</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1239
+ <p class="mis show_mis"><span class="n"><a id="t1157" href="#t1157">1157</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1240
+ <p class="pln"><span class="n"><a id="t1158" href="#t1158">1158</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1241
+ <p class="pln"><span class="n"><a id="t1159" href="#t1159">1159</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
1242
+ <p class="mis show_mis"><span class="n"><a id="t1160" href="#t1160">1160</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1243
+ <p class="pln"><span class="n"><a id="t1161" href="#t1161">1161</a></span><span class="t"> <span class="str">"prompt.generation.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1244
+ <p class="pln"><span class="n"><a id="t1162" href="#t1162">1162</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
1245
+ <p class="pln"><span class="n"><a id="t1163" href="#t1163">1163</a></span><span class="t"> <span class="str">"prompt.name"</span><span class="op">:</span> <span class="nam">prompt_name</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1246
+ <p class="pln"><span class="n"><a id="t1164" href="#t1164">1164</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1247
+ <p class="pln"><span class="n"><a id="t1165" href="#t1165">1165</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1248
+ <p class="pln"><span class="n"><a id="t1166" href="#t1166">1166</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1249
+ <p class="pln"><span class="n"><a id="t1167" href="#t1167">1167</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1250
+ <p class="mis show_mis"><span class="n"><a id="t1168" href="#t1168">1168</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
1251
+ <p class="pln"><span class="n"><a id="t1169" href="#t1169">1169</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1252
+ <p class="mis show_mis"><span class="n"><a id="t1170" href="#t1170">1170</a></span><span class="t"> <span class="key">if</span> <span class="nam">asyncio</span><span class="op">.</span><span class="nam">iscoroutinefunction</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1253
+ <p class="mis show_mis"><span class="n"><a id="t1171" href="#t1171">1171</a></span><span class="t"> <span class="key">return</span> <span class="nam">async_wrapper</span>&nbsp;</span><span class="r"></span></p>
1254
+ <p class="pln"><span class="n"><a id="t1172" href="#t1172">1172</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1255
+ <p class="mis show_mis"><span class="n"><a id="t1173" href="#t1173">1173</a></span><span class="t"> <span class="key">return</span> <span class="nam">sync_wrapper</span>&nbsp;</span><span class="r"></span></p>
1256
+ <p class="pln"><span class="n"><a id="t1174" href="#t1174">1174</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1257
+ <p class="pln"><span class="n"><a id="t1175" href="#t1175">1175</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1258
+ <p class="pln"><span class="n"><a id="t1176" href="#t1176">1176</a></span><span class="t"><span class="com"># Add the BoundedSessionTracker class before SessionTracingMiddleware</span>&nbsp;</span><span class="r"></span></p>
1259
+ <p class="mis show_mis"><span class="n"><a id="t1177" href="#t1177">1177</a></span><span class="t"><span class="key">class</span> <span class="nam">BoundedSessionTracker</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1260
+ <p class="pln"><span class="n"><a id="t1178" href="#t1178">1178</a></span><span class="t"> <span class="str">"""Memory-safe session tracker with automatic expiration."""</span>&nbsp;</span><span class="r"></span></p>
1261
+ <p class="pln"><span class="n"><a id="t1179" href="#t1179">1179</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1262
+ <p class="mis show_mis"><span class="n"><a id="t1180" href="#t1180">1180</a></span><span class="t"> <span class="key">def</span> <span class="nam">__init__</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">max_sessions</span><span class="op">:</span> <span class="nam">int</span> <span class="op">=</span> <span class="num">1000</span><span class="op">,</span> <span class="nam">session_ttl</span><span class="op">:</span> <span class="nam">int</span> <span class="op">=</span> <span class="num">3600</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1263
+ <p class="mis show_mis"><span class="n"><a id="t1181" href="#t1181">1181</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">max_sessions</span> <span class="op">=</span> <span class="nam">max_sessions</span>&nbsp;</span><span class="r"></span></p>
1264
+ <p class="mis show_mis"><span class="n"><a id="t1182" href="#t1182">1182</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">session_ttl</span> <span class="op">=</span> <span class="nam">session_ttl</span>&nbsp;</span><span class="r"></span></p>
1265
+ <p class="mis show_mis"><span class="n"><a id="t1183" href="#t1183">1183</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">:</span> <span class="nam">OrderedDict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">float</span><span class="op">]</span> <span class="op">=</span> <span class="nam">OrderedDict</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1266
+ <p class="mis show_mis"><span class="n"><a id="t1184" href="#t1184">1184</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">last_cleanup</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1267
+ <p class="pln"><span class="n"><a id="t1185" href="#t1185">1185</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1268
+ <p class="mis show_mis"><span class="n"><a id="t1186" href="#t1186">1186</a></span><span class="t"> <span class="key">def</span> <span class="nam">track_session</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">session_id</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">bool</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1269
+ <p class="pln"><span class="n"><a id="t1187" href="#t1187">1187</a></span><span class="t"> <span class="str">"""Track a session, returns True if it's new."""</span>&nbsp;</span><span class="r"></span></p>
1270
+ <p class="mis show_mis"><span class="n"><a id="t1188" href="#t1188">1188</a></span><span class="t"> <span class="nam">current_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1271
+ <p class="pln"><span class="n"><a id="t1189" href="#t1189">1189</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1272
+ <p class="pln"><span class="n"><a id="t1190" href="#t1190">1190</a></span><span class="t"> <span class="com"># Periodic cleanup (every 5 minutes)</span>&nbsp;</span><span class="r"></span></p>
1273
+ <p class="mis show_mis"><span class="n"><a id="t1191" href="#t1191">1191</a></span><span class="t"> <span class="key">if</span> <span class="nam">current_time</span> <span class="op">-</span> <span class="nam">self</span><span class="op">.</span><span class="nam">last_cleanup</span> <span class="op">></span> <span class="num">300</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1274
+ <p class="mis show_mis"><span class="n"><a id="t1192" href="#t1192">1192</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">_cleanup_expired</span><span class="op">(</span><span class="nam">current_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1275
+ <p class="mis show_mis"><span class="n"><a id="t1193" href="#t1193">1193</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">last_cleanup</span> <span class="op">=</span> <span class="nam">current_time</span>&nbsp;</span><span class="r"></span></p>
1276
+ <p class="pln"><span class="n"><a id="t1194" href="#t1194">1194</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1277
+ <p class="pln"><span class="n"><a id="t1195" href="#t1195">1195</a></span><span class="t"> <span class="com"># Check if session exists and is still valid</span>&nbsp;</span><span class="r"></span></p>
1278
+ <p class="mis show_mis"><span class="n"><a id="t1196" href="#t1196">1196</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id</span> <span class="key">in</span> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1279
+ <p class="pln"><span class="n"><a id="t1197" href="#t1197">1197</a></span><span class="t"> <span class="com"># Move to end (mark as recently used)</span>&nbsp;</span><span class="r"></span></p>
1280
+ <p class="mis show_mis"><span class="n"><a id="t1198" href="#t1198">1198</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">.</span><span class="nam">move_to_end</span><span class="op">(</span><span class="nam">session_id</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1281
+ <p class="mis show_mis"><span class="n"><a id="t1199" href="#t1199">1199</a></span><span class="t"> <span class="key">return</span> <span class="key">False</span>&nbsp;</span><span class="r"></span></p>
1282
+ <p class="pln"><span class="n"><a id="t1200" href="#t1200">1200</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1283
+ <p class="pln"><span class="n"><a id="t1201" href="#t1201">1201</a></span><span class="t"> <span class="com"># New session</span>&nbsp;</span><span class="r"></span></p>
1284
+ <p class="mis show_mis"><span class="n"><a id="t1202" href="#t1202">1202</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">[</span><span class="nam">session_id</span><span class="op">]</span> <span class="op">=</span> <span class="nam">current_time</span>&nbsp;</span><span class="r"></span></p>
1285
+ <p class="pln"><span class="n"><a id="t1203" href="#t1203">1203</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1286
+ <p class="pln"><span class="n"><a id="t1204" href="#t1204">1204</a></span><span class="t"> <span class="com"># Enforce max size</span>&nbsp;</span><span class="r"></span></p>
1287
+ <p class="mis show_mis"><span class="n"><a id="t1205" href="#t1205">1205</a></span><span class="t"> <span class="key">while</span> <span class="nam">len</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">)</span> <span class="op">></span> <span class="nam">self</span><span class="op">.</span><span class="nam">max_sessions</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1288
+ <p class="mis show_mis"><span class="n"><a id="t1206" href="#t1206">1206</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">.</span><span class="nam">popitem</span><span class="op">(</span><span class="nam">last</span><span class="op">=</span><span class="key">False</span><span class="op">)</span> <span class="com"># Remove oldest</span>&nbsp;</span><span class="r"></span></p>
1289
+ <p class="pln"><span class="n"><a id="t1207" href="#t1207">1207</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1290
+ <p class="mis show_mis"><span class="n"><a id="t1208" href="#t1208">1208</a></span><span class="t"> <span class="key">return</span> <span class="key">True</span>&nbsp;</span><span class="r"></span></p>
1291
+ <p class="pln"><span class="n"><a id="t1209" href="#t1209">1209</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1292
+ <p class="mis show_mis"><span class="n"><a id="t1210" href="#t1210">1210</a></span><span class="t"> <span class="key">def</span> <span class="nam">_cleanup_expired</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">current_time</span><span class="op">:</span> <span class="nam">float</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1293
+ <p class="pln"><span class="n"><a id="t1211" href="#t1211">1211</a></span><span class="t"> <span class="str">"""Remove expired sessions."""</span>&nbsp;</span><span class="r"></span></p>
1294
+ <p class="mis show_mis"><span class="n"><a id="t1212" href="#t1212">1212</a></span><span class="t"> <span class="nam">expired</span> <span class="op">=</span> <span class="op">[</span><span class="nam">sid</span> <span class="key">for</span> <span class="nam">sid</span><span class="op">,</span> <span class="nam">timestamp</span> <span class="key">in</span> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">.</span><span class="nam">items</span><span class="op">(</span><span class="op">)</span> <span class="key">if</span> <span class="nam">current_time</span> <span class="op">-</span> <span class="nam">timestamp</span> <span class="op">></span> <span class="nam">self</span><span class="op">.</span><span class="nam">session_ttl</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1295
+ <p class="mis show_mis"><span class="n"><a id="t1213" href="#t1213">1213</a></span><span class="t"> <span class="key">for</span> <span class="nam">sid</span> <span class="key">in</span> <span class="nam">expired</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1296
+ <p class="mis show_mis"><span class="n"><a id="t1214" href="#t1214">1214</a></span><span class="t"> <span class="key">del</span> <span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">[</span><span class="nam">sid</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1297
+ <p class="pln"><span class="n"><a id="t1215" href="#t1215">1215</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1298
+ <p class="mis show_mis"><span class="n"><a id="t1216" href="#t1216">1216</a></span><span class="t"> <span class="key">def</span> <span class="nam">get_active_session_count</span><span class="op">(</span><span class="nam">self</span><span class="op">)</span> <span class="op">-></span> <span class="nam">int</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1299
+ <p class="mis show_mis"><span class="n"><a id="t1217" href="#t1217">1217</a></span><span class="t"> <span class="key">return</span> <span class="nam">len</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">sessions</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1300
+ <p class="pln"><span class="n"><a id="t1218" href="#t1218">1218</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1301
+ <p class="pln"><span class="n"><a id="t1219" href="#t1219">1219</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1302
+ <p class="mis show_mis"><span class="n"><a id="t1220" href="#t1220">1220</a></span><span class="t"><span class="key">class</span> <span class="nam">SessionTracingMiddleware</span><span class="op">(</span><span class="nam">BaseHTTPMiddleware</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1303
+ <p class="mis show_mis"><span class="n"><a id="t1221" href="#t1221">1221</a></span><span class="t"> <span class="key">def</span> <span class="nam">__init__</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">app</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1304
+ <p class="mis show_mis"><span class="n"><a id="t1222" href="#t1222">1222</a></span><span class="t"> <span class="nam">super</span><span class="op">(</span><span class="op">)</span><span class="op">.</span><span class="nam">__init__</span><span class="op">(</span><span class="nam">app</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1305
+ <p class="pln"><span class="n"><a id="t1223" href="#t1223">1223</a></span><span class="t"> <span class="com"># Use memory-safe session tracker instead of unbounded collections</span>&nbsp;</span><span class="r"></span></p>
1306
+ <p class="mis show_mis"><span class="n"><a id="t1224" href="#t1224">1224</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">session_tracker</span> <span class="op">=</span> <span class="nam">BoundedSessionTracker</span><span class="op">(</span><span class="nam">max_sessions</span><span class="op">=</span><span class="num">1000</span><span class="op">,</span> <span class="nam">session_ttl</span><span class="op">=</span><span class="num">3600</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1307
+ <p class="pln"><span class="n"><a id="t1225" href="#t1225">1225</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1308
+ <p class="mis show_mis"><span class="n"><a id="t1226" href="#t1226">1226</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">dispatch</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">request</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="nam">call_next</span><span class="op">:</span> <span class="nam">Callable</span><span class="op">[</span><span class="op">...</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1309
+ <p class="pln"><span class="n"><a id="t1227" href="#t1227">1227</a></span><span class="t"> <span class="com"># Record HTTP request timing</span>&nbsp;</span><span class="r"></span></p>
1310
+ <p class="mis show_mis"><span class="n"><a id="t1228" href="#t1228">1228</a></span><span class="t"> <span class="key">import</span> <span class="nam">time</span>&nbsp;</span><span class="r"></span></p>
1311
+ <p class="pln"><span class="n"><a id="t1229" href="#t1229">1229</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1312
+ <p class="mis show_mis"><span class="n"><a id="t1230" href="#t1230">1230</a></span><span class="t"> <span class="nam">start_time</span> <span class="op">=</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1313
+ <p class="pln"><span class="n"><a id="t1231" href="#t1231">1231</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1314
+ <p class="pln"><span class="n"><a id="t1232" href="#t1232">1232</a></span><span class="t"> <span class="com"># Extract session ID from query params or headers</span>&nbsp;</span><span class="r"></span></p>
1315
+ <p class="mis show_mis"><span class="n"><a id="t1233" href="#t1233">1233</a></span><span class="t"> <span class="nam">session_id</span> <span class="op">=</span> <span class="nam">request</span><span class="op">.</span><span class="nam">query_params</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"session_id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1316
+ <p class="mis show_mis"><span class="n"><a id="t1234" href="#t1234">1234</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">session_id</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1317
+ <p class="pln"><span class="n"><a id="t1235" href="#t1235">1235</a></span><span class="t"> <span class="com"># Check headers as fallback</span>&nbsp;</span><span class="r"></span></p>
1318
+ <p class="mis show_mis"><span class="n"><a id="t1236" href="#t1236">1236</a></span><span class="t"> <span class="nam">session_id</span> <span class="op">=</span> <span class="nam">request</span><span class="op">.</span><span class="nam">headers</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"x-session-id"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1319
+ <p class="pln"><span class="n"><a id="t1237" href="#t1237">1237</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1320
+ <p class="pln"><span class="n"><a id="t1238" href="#t1238">1238</a></span><span class="t"> <span class="com"># Track session metrics using memory-safe tracker</span>&nbsp;</span><span class="r"></span></p>
1321
+ <p class="mis show_mis"><span class="n"><a id="t1239" href="#t1239">1239</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1322
+ <p class="mis show_mis"><span class="n"><a id="t1240" href="#t1240">1240</a></span><span class="t"> <span class="nam">is_new_session</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">session_tracker</span><span class="op">.</span><span class="nam">track_session</span><span class="op">(</span><span class="nam">session_id</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1323
+ <p class="pln"><span class="n"><a id="t1241" href="#t1241">1241</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1324
+ <p class="mis show_mis"><span class="n"><a id="t1242" href="#t1242">1242</a></span><span class="t"> <span class="key">if</span> <span class="nam">is_new_session</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1325
+ <p class="mis show_mis"><span class="n"><a id="t1243" href="#t1243">1243</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1326
+ <p class="mis show_mis"><span class="n"><a id="t1244" href="#t1244">1244</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
1327
+ <p class="pln"><span class="n"><a id="t1245" href="#t1245">1245</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1328
+ <p class="mis show_mis"><span class="n"><a id="t1246" href="#t1246">1246</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1329
+ <p class="mis show_mis"><span class="n"><a id="t1247" href="#t1247">1247</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_session</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1330
+ <p class="mis show_mis"><span class="n"><a id="t1248" href="#t1248">1248</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1331
+ <p class="mis show_mis"><span class="n"><a id="t1249" href="#t1249">1249</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1332
+ <p class="pln"><span class="n"><a id="t1250" href="#t1250">1250</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1333
+ <p class="pln"><span class="n"><a id="t1251" href="#t1251">1251</a></span><span class="t"> <span class="com"># Record session duration for existing sessions</span>&nbsp;</span><span class="r"></span></p>
1334
+ <p class="mis show_mis"><span class="n"><a id="t1252" href="#t1252">1252</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1335
+ <p class="mis show_mis"><span class="n"><a id="t1253" href="#t1253">1253</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
1336
+ <p class="pln"><span class="n"><a id="t1254" href="#t1254">1254</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1337
+ <p class="mis show_mis"><span class="n"><a id="t1255" href="#t1255">1255</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1338
+ <p class="pln"><span class="n"><a id="t1256" href="#t1256">1256</a></span><span class="t"> <span class="com"># Use a default duration since we don't track exact start</span>&nbsp;</span><span class="r"></span></p>
1339
+ <p class="pln"><span class="n"><a id="t1257" href="#t1257">1257</a></span><span class="t"> <span class="com"># times anymore</span>&nbsp;</span><span class="r"></span></p>
1340
+ <p class="pln"><span class="n"><a id="t1258" href="#t1258">1258</a></span><span class="t"> <span class="com"># This is less precise but memory-safe</span>&nbsp;</span><span class="r"></span></p>
1341
+ <p class="mis show_mis"><span class="n"><a id="t1259" href="#t1259">1259</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_session_duration</span><span class="op">(</span><span class="num">300.0</span><span class="op">)</span> <span class="com"># 5 min default</span>&nbsp;</span><span class="r"></span></p>
1342
+ <p class="mis show_mis"><span class="n"><a id="t1260" href="#t1260">1260</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1343
+ <p class="mis show_mis"><span class="n"><a id="t1261" href="#t1261">1261</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1344
+ <p class="pln"><span class="n"><a id="t1262" href="#t1262">1262</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1345
+ <p class="pln"><span class="n"><a id="t1263" href="#t1263">1263</a></span><span class="t"> <span class="com"># Create a descriptive span name based on the request</span>&nbsp;</span><span class="r"></span></p>
1346
+ <p class="mis show_mis"><span class="n"><a id="t1264" href="#t1264">1264</a></span><span class="t"> <span class="nam">method</span> <span class="op">=</span> <span class="nam">request</span><span class="op">.</span><span class="nam">method</span>&nbsp;</span><span class="r"></span></p>
1347
+ <p class="mis show_mis"><span class="n"><a id="t1265" href="#t1265">1265</a></span><span class="t"> <span class="nam">path</span> <span class="op">=</span> <span class="nam">request</span><span class="op">.</span><span class="nam">url</span><span class="op">.</span><span class="nam">path</span>&nbsp;</span><span class="r"></span></p>
1348
+ <p class="pln"><span class="n"><a id="t1266" href="#t1266">1266</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1349
+ <p class="pln"><span class="n"><a id="t1267" href="#t1267">1267</a></span><span class="t"> <span class="com"># Determine the operation type from the path</span>&nbsp;</span><span class="r"></span></p>
1350
+ <p class="mis show_mis"><span class="n"><a id="t1268" href="#t1268">1268</a></span><span class="t"> <span class="nam">operation_type</span> <span class="op">=</span> <span class="str">"unknown"</span>&nbsp;</span><span class="r"></span></p>
1351
+ <p class="mis show_mis"><span class="n"><a id="t1269" href="#t1269">1269</a></span><span class="t"> <span class="key">if</span> <span class="str">"/mcp"</span> <span class="key">in</span> <span class="nam">path</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1352
+ <p class="mis show_mis"><span class="n"><a id="t1270" href="#t1270">1270</a></span><span class="t"> <span class="nam">operation_type</span> <span class="op">=</span> <span class="str">"mcp.request"</span>&nbsp;</span><span class="r"></span></p>
1353
+ <p class="mis show_mis"><span class="n"><a id="t1271" href="#t1271">1271</a></span><span class="t"> <span class="key">elif</span> <span class="str">"/sse"</span> <span class="key">in</span> <span class="nam">path</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1354
+ <p class="mis show_mis"><span class="n"><a id="t1272" href="#t1272">1272</a></span><span class="t"> <span class="nam">operation_type</span> <span class="op">=</span> <span class="str">"sse.stream"</span>&nbsp;</span><span class="r"></span></p>
1355
+ <p class="mis show_mis"><span class="n"><a id="t1273" href="#t1273">1273</a></span><span class="t"> <span class="key">elif</span> <span class="str">"/auth"</span> <span class="key">in</span> <span class="nam">path</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1356
+ <p class="mis show_mis"><span class="n"><a id="t1274" href="#t1274">1274</a></span><span class="t"> <span class="nam">operation_type</span> <span class="op">=</span> <span class="str">"auth"</span>&nbsp;</span><span class="r"></span></p>
1357
+ <p class="pln"><span class="n"><a id="t1275" href="#t1275">1275</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1358
+ <p class="mis show_mis"><span class="n"><a id="t1276" href="#t1276">1276</a></span><span class="t"> <span class="nam">span_name</span> <span class="op">=</span> <span class="str">f"{operation_type}.{method.lower()}"</span>&nbsp;</span><span class="r"></span></p>
1359
+ <p class="pln"><span class="n"><a id="t1277" href="#t1277">1277</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1360
+ <p class="mis show_mis"><span class="n"><a id="t1278" href="#t1278">1278</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1361
+ <p class="mis show_mis"><span class="n"><a id="t1279" href="#t1279">1279</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="nam">span_name</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1362
+ <p class="pln"><span class="n"><a id="t1280" href="#t1280">1280</a></span><span class="t"> <span class="com"># Add essential HTTP attributes</span>&nbsp;</span><span class="r"></span></p>
1363
+ <p class="mis show_mis"><span class="n"><a id="t1281" href="#t1281">1281</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"http.method"</span><span class="op">,</span> <span class="nam">method</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1364
+ <p class="mis show_mis"><span class="n"><a id="t1282" href="#t1282">1282</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"http.target"</span><span class="op">,</span> <span class="nam">path</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1365
+ <p class="mis show_mis"><span class="n"><a id="t1283" href="#t1283">1283</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"http.host"</span><span class="op">,</span> <span class="nam">request</span><span class="op">.</span><span class="nam">url</span><span class="op">.</span><span class="nam">hostname</span> <span class="key">or</span> <span class="str">"unknown"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1366
+ <p class="pln"><span class="n"><a id="t1284" href="#t1284">1284</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1367
+ <p class="pln"><span class="n"><a id="t1285" href="#t1285">1285</a></span><span class="t"> <span class="com"># Add session tracking</span>&nbsp;</span><span class="r"></span></p>
1368
+ <p class="mis show_mis"><span class="n"><a id="t1286" href="#t1286">1286</a></span><span class="t"> <span class="key">if</span> <span class="nam">session_id</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1369
+ <p class="mis show_mis"><span class="n"><a id="t1287" href="#t1287">1287</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1370
+ <p class="mis show_mis"><span class="n"><a id="t1288" href="#t1288">1288</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1371
+ <p class="pln"><span class="n"><a id="t1289" href="#t1289">1289</a></span><span class="t"> <span class="str">"mcp.session.active_count"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1372
+ <p class="pln"><span class="n"><a id="t1290" href="#t1290">1290</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">session_tracker</span><span class="op">.</span><span class="nam">get_active_session_count</span><span class="op">(</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1373
+ <p class="pln"><span class="n"><a id="t1291" href="#t1291">1291</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1374
+ <p class="pln"><span class="n"><a id="t1292" href="#t1292">1292</a></span><span class="t"> <span class="com"># Add to baggage for propagation</span>&nbsp;</span><span class="r"></span></p>
1375
+ <p class="mis show_mis"><span class="n"><a id="t1293" href="#t1293">1293</a></span><span class="t"> <span class="nam">ctx</span> <span class="op">=</span> <span class="nam">baggage</span><span class="op">.</span><span class="nam">set_baggage</span><span class="op">(</span><span class="str">"mcp.session.id"</span><span class="op">,</span> <span class="nam">session_id</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1376
+ <p class="mis show_mis"><span class="n"><a id="t1294" href="#t1294">1294</a></span><span class="t"> <span class="key">from</span> <span class="nam">opentelemetry</span> <span class="key">import</span> <span class="nam">context</span>&nbsp;</span><span class="r"></span></p>
1377
+ <p class="pln"><span class="n"><a id="t1295" href="#t1295">1295</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1378
+ <p class="mis show_mis"><span class="n"><a id="t1296" href="#t1296">1296</a></span><span class="t"> <span class="nam">token</span> <span class="op">=</span> <span class="nam">context</span><span class="op">.</span><span class="nam">attach</span><span class="op">(</span><span class="nam">ctx</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1379
+ <p class="pln"><span class="n"><a id="t1297" href="#t1297">1297</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1380
+ <p class="mis show_mis"><span class="n"><a id="t1298" href="#t1298">1298</a></span><span class="t"> <span class="nam">token</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
1381
+ <p class="pln"><span class="n"><a id="t1299" href="#t1299">1299</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1382
+ <p class="pln"><span class="n"><a id="t1300" href="#t1300">1300</a></span><span class="t"> <span class="com"># Add request size if available</span>&nbsp;</span><span class="r"></span></p>
1383
+ <p class="mis show_mis"><span class="n"><a id="t1301" href="#t1301">1301</a></span><span class="t"> <span class="nam">content_length</span> <span class="op">=</span> <span class="nam">request</span><span class="op">.</span><span class="nam">headers</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"content-length"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1384
+ <p class="mis show_mis"><span class="n"><a id="t1302" href="#t1302">1302</a></span><span class="t"> <span class="key">if</span> <span class="nam">content_length</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1385
+ <p class="mis show_mis"><span class="n"><a id="t1303" href="#t1303">1303</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"http.request.size"</span><span class="op">,</span> <span class="nam">int</span><span class="op">(</span><span class="nam">content_length</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1386
+ <p class="pln"><span class="n"><a id="t1304" href="#t1304">1304</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1387
+ <p class="pln"><span class="n"><a id="t1305" href="#t1305">1305</a></span><span class="t"> <span class="com"># Add event for request start</span>&nbsp;</span><span class="r"></span></p>
1388
+ <p class="mis show_mis"><span class="n"><a id="t1306" href="#t1306">1306</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span><span class="str">"http.request.started"</span><span class="op">,</span> <span class="op">{</span><span class="str">"method"</span><span class="op">:</span> <span class="nam">method</span><span class="op">,</span> <span class="str">"path"</span><span class="op">:</span> <span class="nam">path</span><span class="op">}</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1389
+ <p class="pln"><span class="n"><a id="t1307" href="#t1307">1307</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1390
+ <p class="mis show_mis"><span class="n"><a id="t1308" href="#t1308">1308</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1391
+ <p class="mis show_mis"><span class="n"><a id="t1309" href="#t1309">1309</a></span><span class="t"> <span class="nam">response</span> <span class="op">=</span> <span class="key">await</span> <span class="nam">call_next</span><span class="op">(</span><span class="nam">request</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1392
+ <p class="pln"><span class="n"><a id="t1310" href="#t1310">1310</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1393
+ <p class="pln"><span class="n"><a id="t1311" href="#t1311">1311</a></span><span class="t"> <span class="com"># Add response attributes</span>&nbsp;</span><span class="r"></span></p>
1394
+ <p class="mis show_mis"><span class="n"><a id="t1312" href="#t1312">1312</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"http.status_code"</span><span class="op">,</span> <span class="nam">response</span><span class="op">.</span><span class="nam">status_code</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1395
+ <p class="pln"><span class="n"><a id="t1313" href="#t1313">1313</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1396
+ <p class="pln"><span class="n"><a id="t1314" href="#t1314">1314</a></span><span class="t"> <span class="com"># Set span status based on HTTP status</span>&nbsp;</span><span class="r"></span></p>
1397
+ <p class="mis show_mis"><span class="n"><a id="t1315" href="#t1315">1315</a></span><span class="t"> <span class="key">if</span> <span class="nam">response</span><span class="op">.</span><span class="nam">status_code</span> <span class="op">>=</span> <span class="num">400</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1398
+ <p class="mis show_mis"><span class="n"><a id="t1316" href="#t1316">1316</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="str">f"HTTP {response.status_code}"</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1399
+ <p class="pln"><span class="n"><a id="t1317" href="#t1317">1317</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1400
+ <p class="mis show_mis"><span class="n"><a id="t1318" href="#t1318">1318</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">OK</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1401
+ <p class="pln"><span class="n"><a id="t1319" href="#t1319">1319</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1402
+ <p class="pln"><span class="n"><a id="t1320" href="#t1320">1320</a></span><span class="t"> <span class="com"># Add event for request completion</span>&nbsp;</span><span class="r"></span></p>
1403
+ <p class="mis show_mis"><span class="n"><a id="t1321" href="#t1321">1321</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1404
+ <p class="pln"><span class="n"><a id="t1322" href="#t1322">1322</a></span><span class="t"> <span class="str">"http.request.completed"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1405
+ <p class="pln"><span class="n"><a id="t1323" href="#t1323">1323</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
1406
+ <p class="pln"><span class="n"><a id="t1324" href="#t1324">1324</a></span><span class="t"> <span class="str">"method"</span><span class="op">:</span> <span class="nam">method</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1407
+ <p class="pln"><span class="n"><a id="t1325" href="#t1325">1325</a></span><span class="t"> <span class="str">"path"</span><span class="op">:</span> <span class="nam">path</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1408
+ <p class="pln"><span class="n"><a id="t1326" href="#t1326">1326</a></span><span class="t"> <span class="str">"status_code"</span><span class="op">:</span> <span class="nam">response</span><span class="op">.</span><span class="nam">status_code</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1409
+ <p class="pln"><span class="n"><a id="t1327" href="#t1327">1327</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1410
+ <p class="pln"><span class="n"><a id="t1328" href="#t1328">1328</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1411
+ <p class="pln"><span class="n"><a id="t1329" href="#t1329">1329</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1412
+ <p class="pln"><span class="n"><a id="t1330" href="#t1330">1330</a></span><span class="t"> <span class="com"># Record HTTP request metrics</span>&nbsp;</span><span class="r"></span></p>
1413
+ <p class="mis show_mis"><span class="n"><a id="t1331" href="#t1331">1331</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1414
+ <p class="mis show_mis"><span class="n"><a id="t1332" href="#t1332">1332</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
1415
+ <p class="pln"><span class="n"><a id="t1333" href="#t1333">1333</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1416
+ <p class="mis show_mis"><span class="n"><a id="t1334" href="#t1334">1334</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1417
+ <p class="pln"><span class="n"><a id="t1335" href="#t1335">1335</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1418
+ <p class="pln"><span class="n"><a id="t1336" href="#t1336">1336</a></span><span class="t"> <span class="com"># Clean up path for metrics (remove query params, normalize)</span>&nbsp;</span><span class="r"></span></p>
1419
+ <p class="mis show_mis"><span class="n"><a id="t1337" href="#t1337">1337</a></span><span class="t"> <span class="nam">clean_path</span> <span class="op">=</span> <span class="nam">path</span><span class="op">.</span><span class="nam">split</span><span class="op">(</span><span class="str">"?"</span><span class="op">)</span><span class="op">[</span><span class="num">0</span><span class="op">]</span> <span class="com"># Remove query parameters</span>&nbsp;</span><span class="r"></span></p>
1420
+ <p class="mis show_mis"><span class="n"><a id="t1338" href="#t1338">1338</a></span><span class="t"> <span class="key">if</span> <span class="nam">clean_path</span><span class="op">.</span><span class="nam">startswith</span><span class="op">(</span><span class="str">"/"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1421
+ <p class="mis show_mis"><span class="n"><a id="t1339" href="#t1339">1339</a></span><span class="t"> <span class="nam">clean_path</span> <span class="op">=</span> <span class="nam">clean_path</span><span class="op">[</span><span class="num">1</span><span class="op">:</span><span class="op">]</span> <span class="key">or</span> <span class="str">"root"</span> <span class="com"># Remove leading slash, handle root</span>&nbsp;</span><span class="r"></span></p>
1422
+ <p class="pln"><span class="n"><a id="t1340" href="#t1340">1340</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1423
+ <p class="mis show_mis"><span class="n"><a id="t1341" href="#t1341">1341</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_http_request</span><span class="op">(</span><span class="nam">method</span><span class="op">,</span> <span class="nam">response</span><span class="op">.</span><span class="nam">status_code</span><span class="op">,</span> <span class="nam">clean_path</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1424
+ <p class="mis show_mis"><span class="n"><a id="t1342" href="#t1342">1342</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">record_http_duration</span><span class="op">(</span><span class="nam">method</span><span class="op">,</span> <span class="nam">clean_path</span><span class="op">,</span> <span class="nam">time</span><span class="op">.</span><span class="nam">time</span><span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="nam">start_time</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1425
+ <p class="mis show_mis"><span class="n"><a id="t1343" href="#t1343">1343</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1426
+ <p class="pln"><span class="n"><a id="t1344" href="#t1344">1344</a></span><span class="t"> <span class="com"># Metrics not available, continue without metrics</span>&nbsp;</span><span class="r"></span></p>
1427
+ <p class="mis show_mis"><span class="n"><a id="t1345" href="#t1345">1345</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1428
+ <p class="pln"><span class="n"><a id="t1346" href="#t1346">1346</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1429
+ <p class="mis show_mis"><span class="n"><a id="t1347" href="#t1347">1347</a></span><span class="t"> <span class="key">return</span> <span class="nam">response</span>&nbsp;</span><span class="r"></span></p>
1430
+ <p class="mis show_mis"><span class="n"><a id="t1348" href="#t1348">1348</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1431
+ <p class="mis show_mis"><span class="n"><a id="t1349" href="#t1349">1349</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">record_exception</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1432
+ <p class="mis show_mis"><span class="n"><a id="t1350" href="#t1350">1350</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_status</span><span class="op">(</span><span class="nam">Status</span><span class="op">(</span><span class="nam">StatusCode</span><span class="op">.</span><span class="nam">ERROR</span><span class="op">,</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1433
+ <p class="pln"><span class="n"><a id="t1351" href="#t1351">1351</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1434
+ <p class="pln"><span class="n"><a id="t1352" href="#t1352">1352</a></span><span class="t"> <span class="com"># Add event for error</span>&nbsp;</span><span class="r"></span></p>
1435
+ <p class="mis show_mis"><span class="n"><a id="t1353" href="#t1353">1353</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">add_event</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
1436
+ <p class="pln"><span class="n"><a id="t1354" href="#t1354">1354</a></span><span class="t"> <span class="str">"http.request.error"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1437
+ <p class="pln"><span class="n"><a id="t1355" href="#t1355">1355</a></span><span class="t"> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
1438
+ <p class="pln"><span class="n"><a id="t1356" href="#t1356">1356</a></span><span class="t"> <span class="str">"method"</span><span class="op">:</span> <span class="nam">method</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1439
+ <p class="pln"><span class="n"><a id="t1357" href="#t1357">1357</a></span><span class="t"> <span class="str">"path"</span><span class="op">:</span> <span class="nam">path</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1440
+ <p class="pln"><span class="n"><a id="t1358" href="#t1358">1358</a></span><span class="t"> <span class="str">"error.type"</span><span class="op">:</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1441
+ <p class="pln"><span class="n"><a id="t1359" href="#t1359">1359</a></span><span class="t"> <span class="str">"error.message"</span><span class="op">:</span> <span class="nam">str</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1442
+ <p class="pln"><span class="n"><a id="t1360" href="#t1360">1360</a></span><span class="t"> <span class="op">}</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1443
+ <p class="pln"><span class="n"><a id="t1361" href="#t1361">1361</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1444
+ <p class="pln"><span class="n"><a id="t1362" href="#t1362">1362</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1445
+ <p class="pln"><span class="n"><a id="t1363" href="#t1363">1363</a></span><span class="t"> <span class="com"># Record HTTP error metrics</span>&nbsp;</span><span class="r"></span></p>
1446
+ <p class="mis show_mis"><span class="n"><a id="t1364" href="#t1364">1364</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1447
+ <p class="mis show_mis"><span class="n"><a id="t1365" href="#t1365">1365</a></span><span class="t"> <span class="key">from</span> <span class="nam">golf</span><span class="op">.</span><span class="nam">metrics</span> <span class="key">import</span> <span class="nam">get_metrics_collector</span>&nbsp;</span><span class="r"></span></p>
1448
+ <p class="pln"><span class="n"><a id="t1366" href="#t1366">1366</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1449
+ <p class="mis show_mis"><span class="n"><a id="t1367" href="#t1367">1367</a></span><span class="t"> <span class="nam">metrics_collector</span> <span class="op">=</span> <span class="nam">get_metrics_collector</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1450
+ <p class="pln"><span class="n"><a id="t1368" href="#t1368">1368</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1451
+ <p class="pln"><span class="n"><a id="t1369" href="#t1369">1369</a></span><span class="t"> <span class="com"># Clean up path for metrics</span>&nbsp;</span><span class="r"></span></p>
1452
+ <p class="mis show_mis"><span class="n"><a id="t1370" href="#t1370">1370</a></span><span class="t"> <span class="nam">clean_path</span> <span class="op">=</span> <span class="nam">path</span><span class="op">.</span><span class="nam">split</span><span class="op">(</span><span class="str">"?"</span><span class="op">)</span><span class="op">[</span><span class="num">0</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1453
+ <p class="mis show_mis"><span class="n"><a id="t1371" href="#t1371">1371</a></span><span class="t"> <span class="key">if</span> <span class="nam">clean_path</span><span class="op">.</span><span class="nam">startswith</span><span class="op">(</span><span class="str">"/"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1454
+ <p class="mis show_mis"><span class="n"><a id="t1372" href="#t1372">1372</a></span><span class="t"> <span class="nam">clean_path</span> <span class="op">=</span> <span class="nam">clean_path</span><span class="op">[</span><span class="num">1</span><span class="op">:</span><span class="op">]</span> <span class="key">or</span> <span class="str">"root"</span>&nbsp;</span><span class="r"></span></p>
1455
+ <p class="pln"><span class="n"><a id="t1373" href="#t1373">1373</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1456
+ <p class="mis show_mis"><span class="n"><a id="t1374" href="#t1374">1374</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_http_request</span><span class="op">(</span><span class="nam">method</span><span class="op">,</span> <span class="num">500</span><span class="op">,</span> <span class="nam">clean_path</span><span class="op">)</span> <span class="com"># Assume 500 for exceptions</span>&nbsp;</span><span class="r"></span></p>
1457
+ <p class="mis show_mis"><span class="n"><a id="t1375" href="#t1375">1375</a></span><span class="t"> <span class="nam">metrics_collector</span><span class="op">.</span><span class="nam">increment_error</span><span class="op">(</span><span class="str">"http"</span><span class="op">,</span> <span class="nam">type</span><span class="op">(</span><span class="nam">e</span><span class="op">)</span><span class="op">.</span><span class="nam">__name__</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1458
+ <p class="mis show_mis"><span class="n"><a id="t1376" href="#t1376">1376</a></span><span class="t"> <span class="key">except</span> <span class="nam">ImportError</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1459
+ <p class="mis show_mis"><span class="n"><a id="t1377" href="#t1377">1377</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1460
+ <p class="pln"><span class="n"><a id="t1378" href="#t1378">1378</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1461
+ <p class="mis show_mis"><span class="n"><a id="t1379" href="#t1379">1379</a></span><span class="t"> <span class="key">raise</span>&nbsp;</span><span class="r"></span></p>
1462
+ <p class="pln"><span class="n"><a id="t1380" href="#t1380">1380</a></span><span class="t"> <span class="key">finally</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1463
+ <p class="mis show_mis"><span class="n"><a id="t1381" href="#t1381">1381</a></span><span class="t"> <span class="key">if</span> <span class="nam">token</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1464
+ <p class="mis show_mis"><span class="n"><a id="t1382" href="#t1382">1382</a></span><span class="t"> <span class="nam">context</span><span class="op">.</span><span class="nam">detach</span><span class="op">(</span><span class="nam">token</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1465
+ <p class="pln"><span class="n"><a id="t1383" href="#t1383">1383</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1466
+ <p class="pln"><span class="n"><a id="t1384" href="#t1384">1384</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1467
+ <p class="mis show_mis"><span class="n"><a id="t1385" href="#t1385">1385</a></span><span class="t"><span class="op">@</span><span class="nam">asynccontextmanager</span>&nbsp;</span><span class="r"></span></p>
1468
+ <p class="mis show_mis"><span class="n"><a id="t1386" href="#t1386">1386</a></span><span class="t"><span class="key">async</span> <span class="key">def</span> <span class="nam">telemetry_lifespan</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">AsyncGenerator</span><span class="op">[</span><span class="key">None</span><span class="op">,</span> <span class="key">None</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1469
+ <p class="pln"><span class="n"><a id="t1387" href="#t1387">1387</a></span><span class="t"> <span class="str">"""Simplified lifespan for telemetry initialization and cleanup."""</span>&nbsp;</span><span class="r"></span></p>
1470
+ <p class="pln"><span class="n"><a id="t1388" href="#t1388">1388</a></span><span class="t"> <span class="key">global</span> <span class="nam">_provider</span>&nbsp;</span><span class="r"></span></p>
1471
+ <p class="pln"><span class="n"><a id="t1389" href="#t1389">1389</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1472
+ <p class="pln"><span class="n"><a id="t1390" href="#t1390">1390</a></span><span class="t"> <span class="com"># Initialize telemetry with the server name</span>&nbsp;</span><span class="r"></span></p>
1473
+ <p class="mis show_mis"><span class="n"><a id="t1391" href="#t1391">1391</a></span><span class="t"> <span class="nam">provider</span> <span class="op">=</span> <span class="nam">init_telemetry</span><span class="op">(</span><span class="nam">service_name</span><span class="op">=</span><span class="nam">mcp_instance</span><span class="op">.</span><span class="nam">name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1474
+ <p class="pln"><span class="n"><a id="t1392" href="#t1392">1392</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1475
+ <p class="pln"><span class="n"><a id="t1393" href="#t1393">1393</a></span><span class="t"> <span class="com"># If provider is None, telemetry is disabled</span>&nbsp;</span><span class="r"></span></p>
1476
+ <p class="mis show_mis"><span class="n"><a id="t1394" href="#t1394">1394</a></span><span class="t"> <span class="key">if</span> <span class="nam">provider</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1477
+ <p class="pln"><span class="n"><a id="t1395" href="#t1395">1395</a></span><span class="t"> <span class="com"># Just yield without any telemetry setup</span>&nbsp;</span><span class="r"></span></p>
1478
+ <p class="mis show_mis"><span class="n"><a id="t1396" href="#t1396">1396</a></span><span class="t"> <span class="key">yield</span>&nbsp;</span><span class="r"></span></p>
1479
+ <p class="mis show_mis"><span class="n"><a id="t1397" href="#t1397">1397</a></span><span class="t"> <span class="key">return</span>&nbsp;</span><span class="r"></span></p>
1480
+ <p class="pln"><span class="n"><a id="t1398" href="#t1398">1398</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1481
+ <p class="pln"><span class="n"><a id="t1399" href="#t1399">1399</a></span><span class="t"> <span class="com"># Try to add session tracking middleware if possible</span>&nbsp;</span><span class="r"></span></p>
1482
+ <p class="mis show_mis"><span class="n"><a id="t1400" href="#t1400">1400</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1483
+ <p class="pln"><span class="n"><a id="t1401" href="#t1401">1401</a></span><span class="t"> <span class="com"># Try to add middleware to FastMCP app if it has Starlette app</span>&nbsp;</span><span class="r"></span></p>
1484
+ <p class="mis show_mis"><span class="n"><a id="t1402" href="#t1402">1402</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">,</span> <span class="str">"app"</span><span class="op">)</span> <span class="key">or</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">,</span> <span class="str">"_app"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1485
+ <p class="mis show_mis"><span class="n"><a id="t1403" href="#t1403">1403</a></span><span class="t"> <span class="nam">app</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">,</span> <span class="str">"app"</span><span class="op">,</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">,</span> <span class="str">"_app"</span><span class="op">,</span> <span class="key">None</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1486
+ <p class="mis show_mis"><span class="n"><a id="t1404" href="#t1404">1404</a></span><span class="t"> <span class="key">if</span> <span class="nam">app</span> <span class="key">and</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">app</span><span class="op">,</span> <span class="str">"add_middleware"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1487
+ <p class="mis show_mis"><span class="n"><a id="t1405" href="#t1405">1405</a></span><span class="t"> <span class="nam">app</span><span class="op">.</span><span class="nam">add_middleware</span><span class="op">(</span><span class="nam">SessionTracingMiddleware</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1488
+ <p class="pln"><span class="n"><a id="t1406" href="#t1406">1406</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1489
+ <p class="pln"><span class="n"><a id="t1407" href="#t1407">1407</a></span><span class="t"> <span class="com"># Also try to instrument FastMCP's internal handlers</span>&nbsp;</span><span class="r"></span></p>
1490
+ <p class="mis show_mis"><span class="n"><a id="t1408" href="#t1408">1408</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">,</span> <span class="str">"_tool_manager"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">.</span><span class="nam">_tool_manager</span><span class="op">,</span> <span class="str">"tools"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1491
+ <p class="pln"><span class="n"><a id="t1409" href="#t1409">1409</a></span><span class="t"> <span class="com"># The tools should already be instrumented when they were registered</span>&nbsp;</span><span class="r"></span></p>
1492
+ <p class="mis show_mis"><span class="n"><a id="t1410" href="#t1410">1410</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
1493
+ <p class="pln"><span class="n"><a id="t1411" href="#t1411">1411</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1494
+ <p class="pln"><span class="n"><a id="t1412" href="#t1412">1412</a></span><span class="t"> <span class="com"># Try to patch FastMCP's request handling to ensure context propagation</span>&nbsp;</span><span class="r"></span></p>
1495
+ <p class="mis show_mis"><span class="n"><a id="t1413" href="#t1413">1413</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">mcp_instance</span><span class="op">,</span> <span class="str">"handle_request"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1496
+ <p class="mis show_mis"><span class="n"><a id="t1414" href="#t1414">1414</a></span><span class="t"> <span class="nam">original_handle_request</span> <span class="op">=</span> <span class="nam">mcp_instance</span><span class="op">.</span><span class="nam">handle_request</span>&nbsp;</span><span class="r"></span></p>
1497
+ <p class="pln"><span class="n"><a id="t1415" href="#t1415">1415</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1498
+ <p class="mis show_mis"><span class="n"><a id="t1416" href="#t1416">1416</a></span><span class="t"> <span class="key">async</span> <span class="key">def</span> <span class="nam">traced_handle_request</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">Any</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1499
+ <p class="mis show_mis"><span class="n"><a id="t1417" href="#t1417">1417</a></span><span class="t"> <span class="nam">tracer</span> <span class="op">=</span> <span class="nam">get_tracer</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1500
+ <p class="mis show_mis"><span class="n"><a id="t1418" href="#t1418">1418</a></span><span class="t"> <span class="key">with</span> <span class="nam">tracer</span><span class="op">.</span><span class="nam">start_as_current_span</span><span class="op">(</span><span class="str">"mcp.handle_request"</span><span class="op">)</span> <span class="key">as</span> <span class="nam">span</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1501
+ <p class="mis show_mis"><span class="n"><a id="t1419" href="#t1419">1419</a></span><span class="t"> <span class="nam">span</span><span class="op">.</span><span class="nam">set_attribute</span><span class="op">(</span><span class="str">"mcp.request.handler"</span><span class="op">,</span> <span class="str">"handle_request"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1502
+ <p class="mis show_mis"><span class="n"><a id="t1420" href="#t1420">1420</a></span><span class="t"> <span class="key">return</span> <span class="key">await</span> <span class="nam">original_handle_request</span><span class="op">(</span><span class="op">*</span><span class="nam">args</span><span class="op">,</span> <span class="op">**</span><span class="nam">kwargs</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1503
+ <p class="pln"><span class="n"><a id="t1421" href="#t1421">1421</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1504
+ <p class="mis show_mis"><span class="n"><a id="t1422" href="#t1422">1422</a></span><span class="t"> <span class="nam">mcp_instance</span><span class="op">.</span><span class="nam">handle_request</span> <span class="op">=</span> <span class="nam">traced_handle_request</span>&nbsp;</span><span class="r"></span></p>
1505
+ <p class="pln"><span class="n"><a id="t1423" href="#t1423">1423</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1506
+ <p class="mis show_mis"><span class="n"><a id="t1424" href="#t1424">1424</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1507
+ <p class="pln"><span class="n"><a id="t1425" href="#t1425">1425</a></span><span class="t"> <span class="com"># Silently continue if middleware setup fails</span>&nbsp;</span><span class="r"></span></p>
1508
+ <p class="mis show_mis"><span class="n"><a id="t1426" href="#t1426">1426</a></span><span class="t"> <span class="key">import</span> <span class="nam">traceback</span>&nbsp;</span><span class="r"></span></p>
1509
+ <p class="pln"><span class="n"><a id="t1427" href="#t1427">1427</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1510
+ <p class="mis show_mis"><span class="n"><a id="t1428" href="#t1428">1428</a></span><span class="t"> <span class="nam">traceback</span><span class="op">.</span><span class="nam">print_exc</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1511
+ <p class="pln"><span class="n"><a id="t1429" href="#t1429">1429</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1512
+ <p class="mis show_mis"><span class="n"><a id="t1430" href="#t1430">1430</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1513
+ <p class="pln"><span class="n"><a id="t1431" href="#t1431">1431</a></span><span class="t"> <span class="com"># Yield control back to FastMCP</span>&nbsp;</span><span class="r"></span></p>
1514
+ <p class="mis show_mis"><span class="n"><a id="t1432" href="#t1432">1432</a></span><span class="t"> <span class="key">yield</span>&nbsp;</span><span class="r"></span></p>
1515
+ <p class="pln"><span class="n"><a id="t1433" href="#t1433">1433</a></span><span class="t"> <span class="key">finally</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1516
+ <p class="pln"><span class="n"><a id="t1434" href="#t1434">1434</a></span><span class="t"> <span class="com"># Cleanup - shutdown the provider</span>&nbsp;</span><span class="r"></span></p>
1517
+ <p class="mis show_mis"><span class="n"><a id="t1435" href="#t1435">1435</a></span><span class="t"> <span class="key">if</span> <span class="nam">_provider</span> <span class="key">and</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">_provider</span><span class="op">,</span> <span class="str">"shutdown"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1518
+ <p class="mis show_mis"><span class="n"><a id="t1436" href="#t1436">1436</a></span><span class="t"> <span class="nam">_provider</span><span class="op">.</span><span class="nam">force_flush</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1519
+ <p class="mis show_mis"><span class="n"><a id="t1437" href="#t1437">1437</a></span><span class="t"> <span class="nam">_provider</span><span class="op">.</span><span class="nam">shutdown</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1520
+ <p class="mis show_mis"><span class="n"><a id="t1438" href="#t1438">1438</a></span><span class="t"> <span class="nam">_provider</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
1521
+ </main>
1522
+ <footer>
1523
+ <div class="content">
1524
+ <p>
1525
+ <a class="nav" href="z_3ec3b3f490dc0950___init___py.html">&#xab; prev</a> &nbsp; &nbsp;
1526
+ <a class="nav" href="index.html">&Hat; index</a> &nbsp; &nbsp;
1527
+ <a class="nav" href="z_abe733142b40ad4e___init___py.html">&#xbb; next</a>
1528
+ &nbsp; &nbsp; &nbsp;
1529
+ <a class="nav" href="https://coverage.readthedocs.io/en/7.6.12">coverage.py v7.6.12</a>,
1530
+ created at 2025-08-16 18:46 +0200
1531
+ </p>
1532
+ </div>
1533
+ </footer>
1534
+ </body>
1535
+ </html>