golf-mcp 0.2.1__py3-none-any.whl → 0.2.3__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 (69) hide show
  1. golf/__init__.py +1 -1
  2. golf/_endpoints.py +2 -2
  3. golf/_endpoints.py.in +6 -0
  4. golf/auth/__init__.py +4 -4
  5. golf/auth/factory.py +4 -2
  6. golf/auth/providers.py +169 -1
  7. golf/core/builder_auth.py +2 -2
  8. {golf_mcp-0.2.1.dist-info → golf_mcp-0.2.3.dist-info}/METADATA +1 -1
  9. golf_mcp-0.2.3.dist-info/RECORD +56 -0
  10. golf/examples/__pycache__/__init__.cpython-311.pyc +0 -0
  11. golf/examples/basic/.coverage +0 -0
  12. golf/examples/basic/__pycache__/auth.cpython-311.pyc +0 -0
  13. golf/examples/basic/htmlcov/.gitignore +0 -2
  14. golf/examples/basic/htmlcov/class_index.html +0 -547
  15. golf/examples/basic/htmlcov/coverage_html_cb_6fb7b396.js +0 -733
  16. golf/examples/basic/htmlcov/favicon_32_cb_58284776.png +0 -0
  17. golf/examples/basic/htmlcov/function_index.html +0 -2091
  18. golf/examples/basic/htmlcov/index.html +0 -349
  19. golf/examples/basic/htmlcov/keybd_closed_cb_ce680311.png +0 -0
  20. golf/examples/basic/htmlcov/status.json +0 -1
  21. golf/examples/basic/htmlcov/style_cb_8e611ae1.css +0 -337
  22. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496___init___py.html +0 -323
  23. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_api_key_py.html +0 -170
  24. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_factory_py.html +0 -430
  25. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_helpers_py.html +0 -288
  26. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_providers_py.html +0 -493
  27. golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_registry_py.html +0 -353
  28. golf/examples/basic/htmlcov/z_3ec3b3f490dc0950___init___py.html +0 -120
  29. golf/examples/basic/htmlcov/z_3ec3b3f490dc0950_instrumentation_py.html +0 -1535
  30. golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db___init___py.html +0 -98
  31. golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_branding_py.html +0 -289
  32. golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_main_py.html +0 -476
  33. golf/examples/basic/htmlcov/z_5a6c4e6bcc86fb2f___init___py.html +0 -97
  34. golf/examples/basic/htmlcov/z_6cadab9ec0df475d___init___py.html +0 -102
  35. golf/examples/basic/htmlcov/z_6cadab9ec0df475d_build_py.html +0 -178
  36. golf/examples/basic/htmlcov/z_6cadab9ec0df475d_init_py.html +0 -387
  37. golf/examples/basic/htmlcov/z_6cadab9ec0df475d_run_py.html +0 -222
  38. golf/examples/basic/htmlcov/z_6fcdee0582ba84e4___init___py.html +0 -106
  39. golf/examples/basic/htmlcov/z_6fcdee0582ba84e4__endpoints_fallback_py.html +0 -107
  40. golf/examples/basic/htmlcov/z_7ba499ed22986217___init___py.html +0 -98
  41. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_auth_py.html +0 -306
  42. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_metrics_py.html +0 -329
  43. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_py.html +0 -1471
  44. golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_telemetry_py.html +0 -186
  45. golf/examples/basic/htmlcov/z_7ba499ed22986217_config_py.html +0 -315
  46. golf/examples/basic/htmlcov/z_7ba499ed22986217_parser_py.html +0 -1149
  47. golf/examples/basic/htmlcov/z_7ba499ed22986217_platform_py.html +0 -279
  48. golf/examples/basic/htmlcov/z_7ba499ed22986217_telemetry_py.html +0 -589
  49. golf/examples/basic/htmlcov/z_7ba499ed22986217_transformer_py.html +0 -286
  50. golf/examples/basic/htmlcov/z_7d7da37693a43688___init___py.html +0 -107
  51. golf/examples/basic/htmlcov/z_7d7da37693a43688_collector_py.html +0 -417
  52. golf/examples/basic/htmlcov/z_7d7da37693a43688_registry_py.html +0 -109
  53. golf/examples/basic/htmlcov/z_abe733142b40ad4e___init___py.html +0 -109
  54. golf/examples/basic/htmlcov/z_abe733142b40ad4e_context_py.html +0 -150
  55. golf/examples/basic/htmlcov/z_abe733142b40ad4e_elicitation_py.html +0 -267
  56. golf/examples/basic/htmlcov/z_abe733142b40ad4e_sampling_py.html +0 -318
  57. golf/examples/basic/prompts/__pycache__/welcome.cpython-311.pyc +0 -0
  58. golf/examples/basic/resources/__pycache__/current_time.cpython-311.pyc +0 -0
  59. golf/examples/basic/resources/__pycache__/info.cpython-311.pyc +0 -0
  60. golf/examples/basic/resources/weather/__pycache__/common.cpython-311.pyc +0 -0
  61. golf/examples/basic/resources/weather/__pycache__/current.cpython-311.pyc +0 -0
  62. golf/examples/basic/resources/weather/__pycache__/forecast.cpython-311.pyc +0 -0
  63. golf/examples/basic/tools/__pycache__/calculator.cpython-311.pyc +0 -0
  64. golf/examples/basic/tools/say/__pycache__/hello.cpython-311.pyc +0 -0
  65. golf_mcp-0.2.1.dist-info/RECORD +0 -110
  66. {golf_mcp-0.2.1.dist-info → golf_mcp-0.2.3.dist-info}/WHEEL +0 -0
  67. {golf_mcp-0.2.1.dist-info → golf_mcp-0.2.3.dist-info}/entry_points.txt +0 -0
  68. {golf_mcp-0.2.1.dist-info → golf_mcp-0.2.3.dist-info}/licenses/LICENSE +0 -0
  69. {golf_mcp-0.2.1.dist-info → golf_mcp-0.2.3.dist-info}/top_level.txt +0 -0
@@ -1,1149 +0,0 @@
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/core/parser.py: 63%</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/core/parser.py</b>:
15
- <span class="pc_cov">63%</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">585 statements &nbsp;</span>
58
- <button type="button" class="run button_toggle_run" value="run" data-shortcut="r" title="Toggle lines run">368<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">217<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_7ba499ed22986217_config_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_7ba499ed22986217_platform_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">"""Python file parser for extracting tools, resources, and prompts using AST."""</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="run"><span class="n"><a id="t3" href="#t3">3</a></span><span class="t"><span class="key">import</span> <span class="nam">ast</span>&nbsp;</span><span class="r"></span></p>
86
- <p class="run"><span class="n"><a id="t4" href="#t4">4</a></span><span class="t"><span class="key">import</span> <span class="nam">re</span>&nbsp;</span><span class="r"></span></p>
87
- <p class="run"><span class="n"><a id="t5" href="#t5">5</a></span><span class="t"><span class="key">from</span> <span class="nam">dataclasses</span> <span class="key">import</span> <span class="nam">dataclass</span>&nbsp;</span><span class="r"></span></p>
88
- <p class="run"><span class="n"><a id="t6" href="#t6">6</a></span><span class="t"><span class="key">from</span> <span class="nam">enum</span> <span class="key">import</span> <span class="nam">Enum</span>&nbsp;</span><span class="r"></span></p>
89
- <p class="run"><span class="n"><a id="t7" href="#t7">7</a></span><span class="t"><span class="key">from</span> <span class="nam">pathlib</span> <span class="key">import</span> <span class="nam">Path</span>&nbsp;</span><span class="r"></span></p>
90
- <p class="run"><span class="n"><a id="t8" href="#t8">8</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>&nbsp;</span><span class="r"></span></p>
91
- <p class="pln"><span class="n"><a id="t9" href="#t9">9</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
92
- <p class="run"><span class="n"><a id="t10" href="#t10">10</a></span><span class="t"><span class="key">from</span> <span class="nam">rich</span><span class="op">.</span><span class="nam">console</span> <span class="key">import</span> <span class="nam">Console</span>&nbsp;</span><span class="r"></span></p>
93
- <p class="pln"><span class="n"><a id="t11" href="#t11">11</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
94
- <p class="run"><span class="n"><a id="t12" href="#t12">12</a></span><span class="t"><span class="nam">console</span> <span class="op">=</span> <span class="nam">Console</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
95
- <p class="pln"><span class="n"><a id="t13" href="#t13">13</a></span><span class="t">&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="run"><span class="n"><a id="t15" href="#t15">15</a></span><span class="t"><span class="key">class</span> <span class="nam">ComponentType</span><span class="op">(</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Enum</span><span class="op">)</span><span class="op">:</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"> <span class="str">"""Type of component discovered by the parser."""</span>&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">&nbsp;</span><span class="r"></span></p>
100
- <p class="run"><span class="n"><a id="t18" href="#t18">18</a></span><span class="t"> <span class="nam">TOOL</span> <span class="op">=</span> <span class="str">"tool"</span>&nbsp;</span><span class="r"></span></p>
101
- <p class="run"><span class="n"><a id="t19" href="#t19">19</a></span><span class="t"> <span class="nam">RESOURCE</span> <span class="op">=</span> <span class="str">"resource"</span>&nbsp;</span><span class="r"></span></p>
102
- <p class="run"><span class="n"><a id="t20" href="#t20">20</a></span><span class="t"> <span class="nam">PROMPT</span> <span class="op">=</span> <span class="str">"prompt"</span>&nbsp;</span><span class="r"></span></p>
103
- <p class="run"><span class="n"><a id="t21" href="#t21">21</a></span><span class="t"> <span class="nam">ROUTE</span> <span class="op">=</span> <span class="str">"route"</span>&nbsp;</span><span class="r"></span></p>
104
- <p class="run"><span class="n"><a id="t22" href="#t22">22</a></span><span class="t"> <span class="nam">UNKNOWN</span> <span class="op">=</span> <span class="str">"unknown"</span>&nbsp;</span><span class="r"></span></p>
105
- <p class="pln"><span class="n"><a id="t23" href="#t23">23</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
106
- <p class="pln"><span class="n"><a id="t24" href="#t24">24</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
107
- <p class="run"><span class="n"><a id="t25" href="#t25">25</a></span><span class="t"><span class="op">@</span><span class="nam">dataclass</span>&nbsp;</span><span class="r"></span></p>
108
- <p class="run"><span class="n"><a id="t26" href="#t26">26</a></span><span class="t"><span class="key">class</span> <span class="nam">ParsedComponent</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
109
- <p class="pln"><span class="n"><a id="t27" href="#t27">27</a></span><span class="t"> <span class="str">"""Represents a parsed MCP component (tool, resource, or prompt)."""</span>&nbsp;</span><span class="r"></span></p>
110
- <p class="pln"><span class="n"><a id="t28" href="#t28">28</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
111
- <p class="run"><span class="n"><a id="t29" href="#t29">29</a></span><span class="t"> <span class="nam">name</span><span class="op">:</span> <span class="nam">str</span> <span class="com"># Derived from file path or explicit name</span>&nbsp;</span><span class="r"></span></p>
112
- <p class="run"><span class="n"><a id="t30" href="#t30">30</a></span><span class="t"> <span class="nam">type</span><span class="op">:</span> <span class="nam">ComponentType</span>&nbsp;</span><span class="r"></span></p>
113
- <p class="run"><span class="n"><a id="t31" href="#t31">31</a></span><span class="t"> <span class="nam">file_path</span><span class="op">:</span> <span class="nam">Path</span>&nbsp;</span><span class="r"></span></p>
114
- <p class="run"><span class="n"><a id="t32" href="#t32">32</a></span><span class="t"> <span class="nam">module_path</span><span class="op">:</span> <span class="nam">str</span>&nbsp;</span><span class="r"></span></p>
115
- <p class="run"><span class="n"><a id="t33" href="#t33">33</a></span><span class="t"> <span class="nam">docstring</span><span class="op">:</span> <span class="nam">str</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>
116
- <p class="run"><span class="n"><a id="t34" href="#t34">34</a></span><span class="t"> <span class="nam">input_schema</span><span class="op">:</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
117
- <p class="run"><span class="n"><a id="t35" href="#t35">35</a></span><span class="t"> <span class="nam">output_schema</span><span class="op">:</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
118
- <p class="run"><span class="n"><a id="t36" href="#t36">36</a></span><span class="t"> <span class="nam">uri_template</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="key">None</span> <span class="com"># For resources</span>&nbsp;</span><span class="r"></span></p>
119
- <p class="run"><span class="n"><a id="t37" href="#t37">37</a></span><span class="t"> <span class="nam">parameters</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="key">None</span> <span class="com"># For resources with URI params</span>&nbsp;</span><span class="r"></span></p>
120
- <p class="run"><span class="n"><a id="t38" href="#t38">38</a></span><span class="t"> <span class="nam">parent_module</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="key">None</span> <span class="com"># For nested components</span>&nbsp;</span><span class="r"></span></p>
121
- <p class="run"><span class="n"><a id="t39" href="#t39">39</a></span><span class="t"> <span class="nam">entry_function</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="key">None</span> <span class="com"># Store the name of the function to use</span>&nbsp;</span><span class="r"></span></p>
122
- <p class="run"><span class="n"><a id="t40" href="#t40">40</a></span><span class="t"> <span class="nam">annotations</span><span class="op">:</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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> <span class="key">None</span> <span class="com"># Tool annotations for MCP hints</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">&nbsp;</span><span class="r"></span></p>
124
- <p class="pln"><span class="n"><a id="t42" href="#t42">42</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
125
- <p class="run"><span class="n"><a id="t43" href="#t43">43</a></span><span class="t"><span class="key">class</span> <span class="nam">AstParser</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
126
- <p class="pln"><span class="n"><a id="t44" href="#t44">44</a></span><span class="t"> <span class="str">"""AST-based parser for extracting MCP components from Python files."""</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">&nbsp;</span><span class="r"></span></p>
128
- <p class="run"><span class="n"><a id="t46" href="#t46">46</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">project_root</span><span class="op">:</span> <span class="nam">Path</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>
129
- <p class="pln"><span class="n"><a id="t47" href="#t47">47</a></span><span class="t"> <span class="str">"""Initialize the parser.</span>&nbsp;</span><span class="r"></span></p>
130
- <p class="pln"><span class="n"><a id="t48" href="#t48">48</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
131
- <p class="pln"><span class="n"><a id="t49" href="#t49">49</a></span><span class="t"><span class="str"> Args:</span>&nbsp;</span><span class="r"></span></p>
132
- <p class="pln"><span class="n"><a id="t50" href="#t50">50</a></span><span class="t"><span class="str"> project_root: Root directory of the project</span>&nbsp;</span><span class="r"></span></p>
133
- <p class="pln"><span class="n"><a id="t51" href="#t51">51</a></span><span class="t"><span class="str"> """</span>&nbsp;</span><span class="r"></span></p>
134
- <p class="run"><span class="n"><a id="t52" href="#t52">52</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">project_root</span> <span class="op">=</span> <span class="nam">project_root</span>&nbsp;</span><span class="r"></span></p>
135
- <p class="run"><span class="n"><a id="t53" href="#t53">53</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">components</span><span class="op">:</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">ParsedComponent</span><span class="op">]</span> <span class="op">=</span> <span class="op">{</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
136
- <p class="pln"><span class="n"><a id="t54" href="#t54">54</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
137
- <p class="run"><span class="n"><a id="t55" href="#t55">55</a></span><span class="t"> <span class="key">def</span> <span class="nam">parse_directory</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">directory</span><span class="op">:</span> <span class="nam">Path</span><span class="op">)</span> <span class="op">-></span> <span class="nam">list</span><span class="op">[</span><span class="nam">ParsedComponent</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
138
- <p class="pln"><span class="n"><a id="t56" href="#t56">56</a></span><span class="t"> <span class="str">"""Parse all Python files in a directory recursively."""</span>&nbsp;</span><span class="r"></span></p>
139
- <p class="run"><span class="n"><a id="t57" href="#t57">57</a></span><span class="t"> <span class="nam">components</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&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="run"><span class="n"><a id="t59" href="#t59">59</a></span><span class="t"> <span class="key">for</span> <span class="nam">file_path</span> <span class="key">in</span> <span class="nam">directory</span><span class="op">.</span><span class="nam">glob</span><span class="op">(</span><span class="str">"**/*.py"</span><span class="op">)</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="com"># Skip __pycache__ and other hidden directories</span>&nbsp;</span><span class="r"></span></p>
143
- <p class="run"><span class="n"><a id="t61" href="#t61">61</a></span><span class="t"> <span class="key">if</span> <span class="str">"__pycache__"</span> <span class="key">in</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">parts</span> <span class="key">or</span> <span class="nam">any</span><span class="op">(</span><span class="nam">part</span><span class="op">.</span><span class="nam">startswith</span><span class="op">(</span><span class="str">"."</span><span class="op">)</span> <span class="key">for</span> <span class="nam">part</span> <span class="key">in</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">parts</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
144
- <p class="run"><span class="n"><a id="t62" href="#t62">62</a></span><span class="t"> <span class="key">continue</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="run"><span class="n"><a id="t64" href="#t64">64</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
147
- <p class="run"><span class="n"><a id="t65" href="#t65">65</a></span><span class="t"> <span class="nam">file_components</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">parse_file</span><span class="op">(</span><span class="nam">file_path</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
148
- <p class="run"><span class="n"><a id="t66" href="#t66">66</a></span><span class="t"> <span class="nam">components</span><span class="op">.</span><span class="nam">extend</span><span class="op">(</span><span class="nam">file_components</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
149
- <p class="mis show_mis"><span class="n"><a id="t67" href="#t67">67</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>
150
- <p class="mis show_mis"><span class="n"><a id="t68" href="#t68">68</a></span><span class="t"> <span class="nam">relative_path</span> <span class="op">=</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">project_root</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
151
- <p class="mis show_mis"><span class="n"><a id="t69" href="#t69">69</a></span><span class="t"> <span class="nam">console</span><span class="op">.</span><span class="nam">print</span><span class="op">(</span><span class="str">f"[bold red]Error parsing {relative_path}:[/bold red] {e}"</span><span class="op">)</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">&nbsp;</span><span class="r"></span></p>
153
- <p class="run"><span class="n"><a id="t71" href="#t71">71</a></span><span class="t"> <span class="key">return</span> <span class="nam">components</span>&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">&nbsp;</span><span class="r"></span></p>
155
- <p class="run"><span class="n"><a id="t73" href="#t73">73</a></span><span class="t"> <span class="key">def</span> <span class="nam">parse_file</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">file_path</span><span class="op">:</span> <span class="nam">Path</span><span class="op">)</span> <span class="op">-></span> <span class="nam">list</span><span class="op">[</span><span class="nam">ParsedComponent</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
156
- <p class="pln"><span class="n"><a id="t74" href="#t74">74</a></span><span class="t"> <span class="str">"""Parse a single Python file using AST to extract MCP components."""</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"># Handle common.py files</span>&nbsp;</span><span class="r"></span></p>
158
- <p class="run"><span class="n"><a id="t76" href="#t76">76</a></span><span class="t"> <span class="key">if</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="str">"common.py"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
159
- <p class="pln"><span class="n"><a id="t77" href="#t77">77</a></span><span class="t"> <span class="com"># Register as a known shared module but don't return as a component</span>&nbsp;</span><span class="r"></span></p>
160
- <p class="run"><span class="n"><a id="t78" href="#t78">78</a></span><span class="t"> <span class="key">return</span> <span class="op">[</span><span class="op">]</span>&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">&nbsp;</span><span class="r"></span></p>
162
- <p class="pln"><span class="n"><a id="t80" href="#t80">80</a></span><span class="t"> <span class="com"># Skip __init__.py files for direct parsing</span>&nbsp;</span><span class="r"></span></p>
163
- <p class="run"><span class="n"><a id="t81" href="#t81">81</a></span><span class="t"> <span class="key">if</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="str">"__init__.py"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
164
- <p class="mis show_mis"><span class="n"><a id="t82" href="#t82">82</a></span><span class="t"> <span class="key">return</span> <span class="op">[</span><span class="op">]</span>&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">&nbsp;</span><span class="r"></span></p>
166
- <p class="pln"><span class="n"><a id="t84" href="#t84">84</a></span><span class="t"> <span class="com"># Determine component type based on directory structure</span>&nbsp;</span><span class="r"></span></p>
167
- <p class="run"><span class="n"><a id="t85" href="#t85">85</a></span><span class="t"> <span class="nam">rel_path</span> <span class="op">=</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">project_root</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
168
- <p class="run"><span class="n"><a id="t86" href="#t86">86</a></span><span class="t"> <span class="nam">parent_dir</span> <span class="op">=</span> <span class="nam">rel_path</span><span class="op">.</span><span class="nam">parts</span><span class="op">[</span><span class="num">0</span><span class="op">]</span> <span class="key">if</span> <span class="nam">rel_path</span><span class="op">.</span><span class="nam">parts</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
169
- <p class="pln"><span class="n"><a id="t87" href="#t87">87</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
170
- <p class="run"><span class="n"><a id="t88" href="#t88">88</a></span><span class="t"> <span class="nam">component_type</span> <span class="op">=</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">UNKNOWN</span>&nbsp;</span><span class="r"></span></p>
171
- <p class="run"><span class="n"><a id="t89" href="#t89">89</a></span><span class="t"> <span class="key">if</span> <span class="nam">parent_dir</span> <span class="op">==</span> <span class="str">"tools"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
172
- <p class="run"><span class="n"><a id="t90" href="#t90">90</a></span><span class="t"> <span class="nam">component_type</span> <span class="op">=</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">TOOL</span>&nbsp;</span><span class="r"></span></p>
173
- <p class="run"><span class="n"><a id="t91" href="#t91">91</a></span><span class="t"> <span class="key">elif</span> <span class="nam">parent_dir</span> <span class="op">==</span> <span class="str">"resources"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
174
- <p class="run"><span class="n"><a id="t92" href="#t92">92</a></span><span class="t"> <span class="nam">component_type</span> <span class="op">=</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">RESOURCE</span>&nbsp;</span><span class="r"></span></p>
175
- <p class="run"><span class="n"><a id="t93" href="#t93">93</a></span><span class="t"> <span class="key">elif</span> <span class="nam">parent_dir</span> <span class="op">==</span> <span class="str">"prompts"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
176
- <p class="run"><span class="n"><a id="t94" href="#t94">94</a></span><span class="t"> <span class="nam">component_type</span> <span class="op">=</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">PROMPT</span>&nbsp;</span><span class="r"></span></p>
177
- <p class="pln"><span class="n"><a id="t95" href="#t95">95</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
178
- <p class="run"><span class="n"><a id="t96" href="#t96">96</a></span><span class="t"> <span class="key">if</span> <span class="nam">component_type</span> <span class="op">==</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">UNKNOWN</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
179
- <p class="mis show_mis"><span class="n"><a id="t97" href="#t97">97</a></span><span class="t"> <span class="key">return</span> <span class="op">[</span><span class="op">]</span> <span class="com"># Not in a recognized directory</span>&nbsp;</span><span class="r"></span></p>
180
- <p class="pln"><span class="n"><a id="t98" href="#t98">98</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
181
- <p class="pln"><span class="n"><a id="t99" href="#t99">99</a></span><span class="t"> <span class="com"># Read the file content and parse it with AST</span>&nbsp;</span><span class="r"></span></p>
182
- <p class="run"><span class="n"><a id="t100" href="#t100">100</a></span><span class="t"> <span class="key">with</span> <span class="nam">open</span><span class="op">(</span><span class="nam">file_path</span><span class="op">,</span> <span class="nam">encoding</span><span class="op">=</span><span class="str">"utf-8"</span><span class="op">)</span> <span class="key">as</span> <span class="nam">f</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
183
- <p class="run"><span class="n"><a id="t101" href="#t101">101</a></span><span class="t"> <span class="nam">file_content</span> <span class="op">=</span> <span class="nam">f</span><span class="op">.</span><span class="nam">read</span><span class="op">(</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">&nbsp;</span><span class="r"></span></p>
185
- <p class="run"><span class="n"><a id="t103" href="#t103">103</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
186
- <p class="run"><span class="n"><a id="t104" href="#t104">104</a></span><span class="t"> <span class="nam">tree</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">parse</span><span class="op">(</span><span class="nam">file_content</span><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">except</span> <span class="nam">SyntaxError</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
188
- <p class="mis show_mis"><span class="n"><a id="t106" href="#t106">106</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Syntax error in {file_path}: {e}"</span><span class="op">)</span>&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">&nbsp;</span><span class="r"></span></p>
190
- <p class="pln"><span class="n"><a id="t108" href="#t108">108</a></span><span class="t"> <span class="com"># Extract module docstring</span>&nbsp;</span><span class="r"></span></p>
191
- <p class="run"><span class="n"><a id="t109" href="#t109">109</a></span><span class="t"> <span class="nam">module_docstring</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">get_docstring</span><span class="op">(</span><span class="nam">tree</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
192
- <p class="run"><span class="n"><a id="t110" href="#t110">110</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">module_docstring</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
193
- <p class="run"><span class="n"><a id="t111" href="#t111">111</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Missing module docstring in {file_path}"</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">&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"> <span class="com"># Find the entry function - look for "export = function_name" pattern,</span>&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"># or any top-level function (like "run") as a fallback</span>&nbsp;</span><span class="r"></span></p>
197
- <p class="run"><span class="n"><a id="t115" href="#t115">115</a></span><span class="t"> <span class="nam">entry_function</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
198
- <p class="run"><span class="n"><a id="t116" href="#t116">116</a></span><span class="t"> <span class="nam">export_target</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
199
- <p class="pln"><span class="n"><a id="t117" href="#t117">117</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
200
- <p class="pln"><span class="n"><a id="t118" href="#t118">118</a></span><span class="t"> <span class="com"># Look for export = function_name assignment</span>&nbsp;</span><span class="r"></span></p>
201
- <p class="run"><span class="n"><a id="t119" href="#t119">119</a></span><span class="t"> <span class="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">tree</span><span class="op">.</span><span class="nam">body</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
202
- <p class="run"><span class="n"><a id="t120" href="#t120">120</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Assign</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
203
- <p class="run"><span class="n"><a id="t121" href="#t121">121</a></span><span class="t"> <span class="key">for</span> <span class="nam">target</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">targets</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
204
- <p class="run"><span class="n"><a id="t122" href="#t122">122</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">target</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span> <span class="key">and</span> <span class="nam">target</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"export"</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</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>
205
- <p class="run"><span class="n"><a id="t123" href="#t123">123</a></span><span class="t"> <span class="nam">export_target</span> <span class="op">=</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">id</span>&nbsp;</span><span class="r"></span></p>
206
- <p class="run"><span class="n"><a id="t124" href="#t124">124</a></span><span class="t"> <span class="key">break</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"># Find all top-level functions</span>&nbsp;</span><span class="r"></span></p>
209
- <p class="run"><span class="n"><a id="t127" href="#t127">127</a></span><span class="t"> <span class="nam">functions</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
210
- <p class="run"><span class="n"><a id="t128" href="#t128">128</a></span><span class="t"> <span class="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">tree</span><span class="op">.</span><span class="nam">body</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
211
- <p class="run"><span class="n"><a id="t129" href="#t129">129</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">FunctionDef</span> <span class="op">|</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">AsyncFunctionDef</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
212
- <p class="run"><span class="n"><a id="t130" href="#t130">130</a></span><span class="t"> <span class="nam">functions</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">node</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"> <span class="com"># If this function matches our export target, it's our entry function</span>&nbsp;</span><span class="r"></span></p>
214
- <p class="run"><span class="n"><a id="t132" href="#t132">132</a></span><span class="t"> <span class="key">if</span> <span class="nam">export_target</span> <span class="key">and</span> <span class="nam">node</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="nam">export_target</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
215
- <p class="run"><span class="n"><a id="t133" href="#t133">133</a></span><span class="t"> <span class="nam">entry_function</span> <span class="op">=</span> <span class="nam">node</span>&nbsp;</span><span class="r"></span></p>
216
- <p class="pln"><span class="n"><a id="t134" href="#t134">134</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
217
- <p class="pln"><span class="n"><a id="t135" href="#t135">135</a></span><span class="t"> <span class="com"># Check for the run function as a fallback</span>&nbsp;</span><span class="r"></span></p>
218
- <p class="run"><span class="n"><a id="t136" href="#t136">136</a></span><span class="t"> <span class="nam">run_function</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
219
- <p class="run"><span class="n"><a id="t137" href="#t137">137</a></span><span class="t"> <span class="key">for</span> <span class="nam">func</span> <span class="key">in</span> <span class="nam">functions</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
220
- <p class="run"><span class="n"><a id="t138" href="#t138">138</a></span><span class="t"> <span class="key">if</span> <span class="nam">func</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="str">"run"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
221
- <p class="run"><span class="n"><a id="t139" href="#t139">139</a></span><span class="t"> <span class="nam">run_function</span> <span class="op">=</span> <span class="nam">func</span>&nbsp;</span><span class="r"></span></p>
222
- <p class="pln"><span class="n"><a id="t140" href="#t140">140</a></span><span class="t">&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"> <span class="com"># If we have an export but didn't find the target function, warn</span>&nbsp;</span><span class="r"></span></p>
224
- <p class="run"><span class="n"><a id="t142" href="#t142">142</a></span><span class="t"> <span class="key">if</span> <span class="nam">export_target</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">entry_function</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
225
- <p class="mis show_mis"><span class="n"><a id="t143" href="#t143">143</a></span><span class="t"> <span class="nam">console</span><span class="op">.</span><span class="nam">print</span><span class="op">(</span><span class="str">f"[yellow]Warning: Export target '{export_target}' not found in {file_path}[/yellow]"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
226
- <p class="pln"><span class="n"><a id="t144" href="#t144">144</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
227
- <p class="pln"><span class="n"><a id="t145" href="#t145">145</a></span><span class="t"> <span class="com"># Use the export target function if found, otherwise fall back to run</span>&nbsp;</span><span class="r"></span></p>
228
- <p class="run"><span class="n"><a id="t146" href="#t146">146</a></span><span class="t"> <span class="nam">entry_function</span> <span class="op">=</span> <span class="nam">entry_function</span> <span class="key">or</span> <span class="nam">run_function</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="pln"><span class="n"><a id="t148" href="#t148">148</a></span><span class="t"> <span class="com"># If no valid function found, skip this file</span>&nbsp;</span><span class="r"></span></p>
231
- <p class="run"><span class="n"><a id="t149" href="#t149">149</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">entry_function</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
232
- <p class="mis show_mis"><span class="n"><a id="t150" href="#t150">150</a></span><span class="t"> <span class="key">return</span> <span class="op">[</span><span class="op">]</span>&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">&nbsp;</span><span class="r"></span></p>
234
- <p class="pln"><span class="n"><a id="t152" href="#t152">152</a></span><span class="t"> <span class="com"># Create component</span>&nbsp;</span><span class="r"></span></p>
235
- <p class="run"><span class="n"><a id="t153" href="#t153">153</a></span><span class="t"> <span class="nam">component</span> <span class="op">=</span> <span class="nam">ParsedComponent</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">name</span><span class="op">=</span><span class="str">""</span><span class="op">,</span> <span class="com"># Will be set later</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">type</span><span class="op">=</span><span class="nam">component_type</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">file_path</span><span class="op">=</span><span class="nam">file_path</span><span class="op">,</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="nam">module_path</span><span class="op">=</span><span class="nam">file_path</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">project_root</span><span class="op">)</span><span class="op">.</span><span class="nam">as_posix</span><span class="op">(</span><span class="op">)</span><span class="op">,</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">docstring</span><span class="op">=</span><span class="nam">module_docstring</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">entry_function</span><span class="op">=</span><span class="nam">export_target</span> <span class="key">or</span> <span class="str">"run"</span><span class="op">,</span> <span class="com"># Store the name of the entry function</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="pln"><span class="n"><a id="t161" href="#t161">161</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
244
- <p class="pln"><span class="n"><a id="t162" href="#t162">162</a></span><span class="t"> <span class="com"># Process the entry function</span>&nbsp;</span><span class="r"></span></p>
245
- <p class="run"><span class="n"><a id="t163" href="#t163">163</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">_process_entry_function</span><span class="op">(</span><span class="nam">component</span><span class="op">,</span> <span class="nam">entry_function</span><span class="op">,</span> <span class="nam">tree</span><span class="op">,</span> <span class="nam">file_path</span><span class="op">)</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="pln"><span class="n"><a id="t165" href="#t165">165</a></span><span class="t"> <span class="com"># Process other component-specific information</span>&nbsp;</span><span class="r"></span></p>
248
- <p class="run"><span class="n"><a id="t166" href="#t166">166</a></span><span class="t"> <span class="key">if</span> <span class="nam">component_type</span> <span class="op">==</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">TOOL</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
249
- <p class="run"><span class="n"><a id="t167" href="#t167">167</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">_process_tool</span><span class="op">(</span><span class="nam">component</span><span class="op">,</span> <span class="nam">tree</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
250
- <p class="run"><span class="n"><a id="t168" href="#t168">168</a></span><span class="t"> <span class="key">elif</span> <span class="nam">component_type</span> <span class="op">==</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">RESOURCE</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
251
- <p class="run"><span class="n"><a id="t169" href="#t169">169</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">_process_resource</span><span class="op">(</span><span class="nam">component</span><span class="op">,</span> <span class="nam">tree</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
252
- <p class="run"><span class="n"><a id="t170" href="#t170">170</a></span><span class="t"> <span class="key">elif</span> <span class="nam">component_type</span> <span class="op">==</span> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">PROMPT</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
253
- <p class="run"><span class="n"><a id="t171" href="#t171">171</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">_process_prompt</span><span class="op">(</span><span class="nam">component</span><span class="op">,</span> <span class="nam">tree</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
254
- <p class="pln"><span class="n"><a id="t172" href="#t172">172</a></span><span class="t">&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"># Set component name based on file path</span>&nbsp;</span><span class="r"></span></p>
256
- <p class="run"><span class="n"><a id="t174" href="#t174">174</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">name</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_derive_component_name</span><span class="op">(</span><span class="nam">file_path</span><span class="op">,</span> <span class="nam">component_type</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
257
- <p class="pln"><span class="n"><a id="t175" href="#t175">175</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
258
- <p class="pln"><span class="n"><a id="t176" href="#t176">176</a></span><span class="t"> <span class="com"># Set parent module if it's in a nested structure</span>&nbsp;</span><span class="r"></span></p>
259
- <p class="run"><span class="n"><a id="t177" href="#t177">177</a></span><span class="t"> <span class="key">if</span> <span class="nam">len</span><span class="op">(</span><span class="nam">rel_path</span><span class="op">.</span><span class="nam">parts</span><span class="op">)</span> <span class="op">></span> <span class="num">2</span><span class="op">:</span> <span class="com"># More than just "tools/file.py"</span>&nbsp;</span><span class="r"></span></p>
260
- <p class="run"><span class="n"><a id="t178" href="#t178">178</a></span><span class="t"> <span class="nam">parent_parts</span> <span class="op">=</span> <span class="nam">rel_path</span><span class="op">.</span><span class="nam">parts</span><span class="op">[</span><span class="num">1</span><span class="op">:</span><span class="op">-</span><span class="num">1</span><span class="op">]</span> <span class="com"># Skip the root category and the file itself</span>&nbsp;</span><span class="r"></span></p>
261
- <p class="run"><span class="n"><a id="t179" href="#t179">179</a></span><span class="t"> <span class="key">if</span> <span class="nam">parent_parts</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
262
- <p class="run"><span class="n"><a id="t180" href="#t180">180</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">parent_module</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">parent_parts</span><span class="op">)</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="run"><span class="n"><a id="t182" href="#t182">182</a></span><span class="t"> <span class="key">return</span> <span class="op">[</span><span class="nam">component</span><span class="op">]</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="run"><span class="n"><a id="t184" href="#t184">184</a></span><span class="t"> <span class="key">def</span> <span class="nam">_process_entry_function</span><span class="op">(</span>&nbsp;</span><span class="r"></span></p>
267
- <p class="pln"><span class="n"><a id="t185" href="#t185">185</a></span><span class="t"> <span class="nam">self</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="nam">component</span><span class="op">:</span> <span class="nam">ParsedComponent</span><span class="op">,</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="nam">func_node</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">FunctionDef</span> <span class="op">|</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">AsyncFunctionDef</span><span class="op">,</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"> <span class="nam">tree</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Module</span><span class="op">,</span>&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="nam">file_path</span><span class="op">:</span> <span class="nam">Path</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
272
- <p class="pln"><span class="n"><a id="t190" href="#t190">190</a></span><span class="t"> <span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
273
- <p class="pln"><span class="n"><a id="t191" href="#t191">191</a></span><span class="t"> <span class="str">"""Process the entry function to extract parameters and return type."""</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"> <span class="com"># Check for return annotation - STRICT requirement</span>&nbsp;</span><span class="r"></span></p>
275
- <p class="run"><span class="n"><a id="t193" href="#t193">193</a></span><span class="t"> <span class="key">if</span> <span class="nam">func_node</span><span class="op">.</span><span class="nam">returns</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="run"><span class="n"><a id="t194" href="#t194">194</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Missing return annotation for {func_node.name} function in {file_path}"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
277
- <p class="pln"><span class="n"><a id="t195" href="#t195">195</a></span><span class="t">&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"> <span class="com"># Extract parameter names for basic info</span>&nbsp;</span><span class="r"></span></p>
279
- <p class="run"><span class="n"><a id="t197" href="#t197">197</a></span><span class="t"> <span class="nam">parameters</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
280
- <p class="run"><span class="n"><a id="t198" href="#t198">198</a></span><span class="t"> <span class="key">for</span> <span class="nam">arg</span> <span class="key">in</span> <span class="nam">func_node</span><span class="op">.</span><span class="nam">args</span><span class="op">.</span><span class="nam">args</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="com"># Skip self, cls, ctx parameters</span>&nbsp;</span><span class="r"></span></p>
282
- <p class="run"><span class="n"><a id="t200" href="#t200">200</a></span><span class="t"> <span class="key">if</span> <span class="nam">arg</span><span class="op">.</span><span class="nam">arg</span> <span class="key">not</span> <span class="key">in</span> <span class="op">(</span><span class="str">"self"</span><span class="op">,</span> <span class="str">"cls"</span><span class="op">,</span> <span class="str">"ctx"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
283
- <p class="run"><span class="n"><a id="t201" href="#t201">201</a></span><span class="t"> <span class="nam">parameters</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">arg</span><span class="op">.</span><span class="nam">arg</span><span class="op">)</span>&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">&nbsp;</span><span class="r"></span></p>
285
- <p class="pln"><span class="n"><a id="t203" href="#t203">203</a></span><span class="t"> <span class="com"># Store parameters</span>&nbsp;</span><span class="r"></span></p>
286
- <p class="run"><span class="n"><a id="t204" href="#t204">204</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">parameters</span> <span class="op">=</span> <span class="nam">parameters</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="pln"><span class="n"><a id="t206" href="#t206">206</a></span><span class="t"> <span class="com"># Extract schemas using runtime inspection (safer and more accurate)</span>&nbsp;</span><span class="r"></span></p>
289
- <p class="run"><span class="n"><a id="t207" href="#t207">207</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
290
- <p class="run"><span class="n"><a id="t208" href="#t208">208</a></span><span class="t"> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_schemas_at_runtime</span><span class="op">(</span><span class="nam">component</span><span class="op">,</span> <span class="nam">file_path</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">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>
292
- <p class="mis show_mis"><span class="n"><a id="t210" href="#t210">210</a></span><span class="t"> <span class="nam">console</span><span class="op">.</span><span class="nam">print</span><span class="op">(</span><span class="str">f"[yellow]Warning: Could not extract schemas from {file_path}: {e}[/yellow]"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
293
- <p class="pln"><span class="n"><a id="t211" href="#t211">211</a></span><span class="t"> <span class="com"># Continue without schemas - better than failing the build</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="run"><span class="n"><a id="t213" href="#t213">213</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_schemas_at_runtime</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">component</span><span class="op">:</span> <span class="nam">ParsedComponent</span><span class="op">,</span> <span class="nam">file_path</span><span class="op">:</span> <span class="nam">Path</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>
296
- <p class="pln"><span class="n"><a id="t214" href="#t214">214</a></span><span class="t"> <span class="str">"""Extract input/output schemas by importing and inspecting the</span>&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="str"> actual function."""</span>&nbsp;</span><span class="r"></span></p>
298
- <p class="run"><span class="n"><a id="t216" href="#t216">216</a></span><span class="t"> <span class="key">import</span> <span class="nam">importlib</span><span class="op">.</span><span class="nam">util</span>&nbsp;</span><span class="r"></span></p>
299
- <p class="run"><span class="n"><a id="t217" href="#t217">217</a></span><span class="t"> <span class="key">import</span> <span class="nam">sys</span>&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">&nbsp;</span><span class="r"></span></p>
301
- <p class="pln"><span class="n"><a id="t219" href="#t219">219</a></span><span class="t"> <span class="com"># Convert file path to module name</span>&nbsp;</span><span class="r"></span></p>
302
- <p class="run"><span class="n"><a id="t220" href="#t220">220</a></span><span class="t"> <span class="nam">rel_path</span> <span class="op">=</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">project_root</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
303
- <p class="run"><span class="n"><a id="t221" href="#t221">221</a></span><span class="t"> <span class="nam">module_name</span> <span class="op">=</span> <span class="nam">str</span><span class="op">(</span><span class="nam">rel_path</span><span class="op">.</span><span class="nam">with_suffix</span><span class="op">(</span><span class="str">""</span><span class="op">)</span><span class="op">)</span><span class="op">.</span><span class="nam">replace</span><span class="op">(</span><span class="str">"/"</span><span class="op">,</span> <span class="str">"."</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
304
- <p class="pln"><span class="n"><a id="t222" href="#t222">222</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
305
- <p class="pln"><span class="n"><a id="t223" href="#t223">223</a></span><span class="t"> <span class="com"># Temporarily add project root to sys.path</span>&nbsp;</span><span class="r"></span></p>
306
- <p class="run"><span class="n"><a id="t224" href="#t224">224</a></span><span class="t"> <span class="nam">project_root_str</span> <span class="op">=</span> <span class="nam">str</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">project_root</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
307
- <p class="run"><span class="n"><a id="t225" href="#t225">225</a></span><span class="t"> <span class="key">if</span> <span class="nam">project_root_str</span> <span class="key">not</span> <span class="key">in</span> <span class="nam">sys</span><span class="op">.</span><span class="nam">path</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
308
- <p class="run"><span class="n"><a id="t226" href="#t226">226</a></span><span class="t"> <span class="nam">sys</span><span class="op">.</span><span class="nam">path</span><span class="op">.</span><span class="nam">insert</span><span class="op">(</span><span class="num">0</span><span class="op">,</span> <span class="nam">project_root_str</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
309
- <p class="run"><span class="n"><a id="t227" href="#t227">227</a></span><span class="t"> <span class="nam">cleanup_path</span> <span class="op">=</span> <span class="key">True</span>&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="key">else</span><span class="op">:</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="nam">cleanup_path</span> <span class="op">=</span> <span class="key">False</span>&nbsp;</span><span class="r"></span></p>
312
- <p class="pln"><span class="n"><a id="t230" href="#t230">230</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
313
- <p class="run"><span class="n"><a id="t231" href="#t231">231</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&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"># Import the module</span>&nbsp;</span><span class="r"></span></p>
315
- <p class="run"><span class="n"><a id="t233" href="#t233">233</a></span><span class="t"> <span class="nam">spec</span> <span class="op">=</span> <span class="nam">importlib</span><span class="op">.</span><span class="nam">util</span><span class="op">.</span><span class="nam">spec_from_file_location</span><span class="op">(</span><span class="nam">module_name</span><span class="op">,</span> <span class="nam">file_path</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
316
- <p class="run"><span class="n"><a id="t234" href="#t234">234</a></span><span class="t"> <span class="key">if</span> <span class="nam">spec</span> <span class="key">is</span> <span class="key">None</span> <span class="key">or</span> <span class="nam">spec</span><span class="op">.</span><span class="nam">loader</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</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">return</span>&nbsp;</span><span class="r"></span></p>
318
- <p class="pln"><span class="n"><a id="t236" href="#t236">236</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
319
- <p class="run"><span class="n"><a id="t237" href="#t237">237</a></span><span class="t"> <span class="nam">module</span> <span class="op">=</span> <span class="nam">importlib</span><span class="op">.</span><span class="nam">util</span><span class="op">.</span><span class="nam">module_from_spec</span><span class="op">(</span><span class="nam">spec</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
320
- <p class="run"><span class="n"><a id="t238" href="#t238">238</a></span><span class="t"> <span class="nam">spec</span><span class="op">.</span><span class="nam">loader</span><span class="op">.</span><span class="nam">exec_module</span><span class="op">(</span><span class="nam">module</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"># Get the entry function</span>&nbsp;</span><span class="r"></span></p>
323
- <p class="run"><span class="n"><a id="t241" href="#t241">241</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">module</span><span class="op">,</span> <span class="nam">component</span><span class="op">.</span><span class="nam">entry_function</span><span class="op">)</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">return</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">&nbsp;</span><span class="r"></span></p>
326
- <p class="run"><span class="n"><a id="t244" href="#t244">244</a></span><span class="t"> <span class="nam">func</span> <span class="op">=</span> <span class="nam">getattr</span><span class="op">(</span><span class="nam">module</span><span class="op">,</span> <span class="nam">component</span><span class="op">.</span><span class="nam">entry_function</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">&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="com"># Extract input schema from function signature</span>&nbsp;</span><span class="r"></span></p>
329
- <p class="run"><span class="n"><a id="t247" href="#t247">247</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">input_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_input_schema</span><span class="op">(</span><span class="nam">func</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">&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="com"># Extract output schema from return type annotation</span>&nbsp;</span><span class="r"></span></p>
332
- <p class="run"><span class="n"><a id="t250" href="#t250">250</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">output_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_output_schema</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
333
- <p class="pln"><span class="n"><a id="t251" href="#t251">251</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
334
- <p class="pln"><span class="n"><a id="t252" href="#t252">252</a></span><span class="t"> <span class="key">finally</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
335
- <p class="pln"><span class="n"><a id="t253" href="#t253">253</a></span><span class="t"> <span class="com"># Clean up sys.path</span>&nbsp;</span><span class="r"></span></p>
336
- <p class="run"><span class="n"><a id="t254" href="#t254">254</a></span><span class="t"> <span class="key">if</span> <span class="nam">cleanup_path</span> <span class="key">and</span> <span class="nam">project_root_str</span> <span class="key">in</span> <span class="nam">sys</span><span class="op">.</span><span class="nam">path</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
337
- <p class="run"><span class="n"><a id="t255" href="#t255">255</a></span><span class="t"> <span class="nam">sys</span><span class="op">.</span><span class="nam">path</span><span class="op">.</span><span class="nam">remove</span><span class="op">(</span><span class="nam">project_root_str</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="run"><span class="n"><a id="t257" href="#t257">257</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_input_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">func</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
340
- <p class="pln"><span class="n"><a id="t258" href="#t258">258</a></span><span class="t"> <span class="str">"""Extract input schema from function signature using runtime inspection."""</span>&nbsp;</span><span class="r"></span></p>
341
- <p class="run"><span class="n"><a id="t259" href="#t259">259</a></span><span class="t"> <span class="key">import</span> <span class="nam">inspect</span>&nbsp;</span><span class="r"></span></p>
342
- <p class="run"><span class="n"><a id="t260" href="#t260">260</a></span><span class="t"> <span class="key">from</span> <span class="nam">typing</span> <span class="key">import</span> <span class="nam">get_type_hints</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="run"><span class="n"><a id="t262" href="#t262">262</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
345
- <p class="run"><span class="n"><a id="t263" href="#t263">263</a></span><span class="t"> <span class="nam">sig</span> <span class="op">=</span> <span class="nam">inspect</span><span class="op">.</span><span class="nam">signature</span><span class="op">(</span><span class="nam">func</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
346
- <p class="run"><span class="n"><a id="t264" href="#t264">264</a></span><span class="t"> <span class="nam">type_hints</span> <span class="op">=</span> <span class="nam">get_type_hints</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="nam">include_extras</span><span class="op">=</span><span class="key">True</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
347
- <p class="pln"><span class="n"><a id="t265" href="#t265">265</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
348
- <p class="run"><span class="n"><a id="t266" href="#t266">266</a></span><span class="t"> <span class="nam">properties</span> <span class="op">=</span> <span class="op">{</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
349
- <p class="run"><span class="n"><a id="t267" href="#t267">267</a></span><span class="t"> <span class="nam">required</span> <span class="op">=</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="run"><span class="n"><a id="t269" href="#t269">269</a></span><span class="t"> <span class="key">for</span> <span class="nam">param_name</span><span class="op">,</span> <span class="nam">param</span> <span class="key">in</span> <span class="nam">sig</span><span class="op">.</span><span class="nam">parameters</span><span class="op">.</span><span class="nam">items</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
352
- <p class="pln"><span class="n"><a id="t270" href="#t270">270</a></span><span class="t"> <span class="com"># Skip special parameters</span>&nbsp;</span><span class="r"></span></p>
353
- <p class="run"><span class="n"><a id="t271" href="#t271">271</a></span><span class="t"> <span class="key">if</span> <span class="nam">param_name</span> <span class="key">in</span> <span class="op">(</span><span class="str">"self"</span><span class="op">,</span> <span class="str">"cls"</span><span class="op">,</span> <span class="str">"ctx"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
354
- <p class="mis show_mis"><span class="n"><a id="t272" href="#t272">272</a></span><span class="t"> <span class="key">continue</span>&nbsp;</span><span class="r"></span></p>
355
- <p class="pln"><span class="n"><a id="t273" href="#t273">273</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
356
- <p class="pln"><span class="n"><a id="t274" href="#t274">274</a></span><span class="t"> <span class="com"># Get type hint</span>&nbsp;</span><span class="r"></span></p>
357
- <p class="run"><span class="n"><a id="t275" href="#t275">275</a></span><span class="t"> <span class="key">if</span> <span class="nam">param_name</span> <span class="key">not</span> <span class="key">in</span> <span class="nam">type_hints</span><span class="op">:</span>&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="key">continue</span>&nbsp;</span><span class="r"></span></p>
359
- <p class="pln"><span class="n"><a id="t277" href="#t277">277</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
360
- <p class="run"><span class="n"><a id="t278" href="#t278">278</a></span><span class="t"> <span class="nam">type_hint</span> <span class="op">=</span> <span class="nam">type_hints</span><span class="op">[</span><span class="nam">param_name</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
361
- <p class="pln"><span class="n"><a id="t279" href="#t279">279</a></span><span class="t">&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"># Extract schema for this parameter</span>&nbsp;</span><span class="r"></span></p>
363
- <p class="run"><span class="n"><a id="t281" href="#t281">281</a></span><span class="t"> <span class="nam">param_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_param_schema_from_hint</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">,</span> <span class="nam">param_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
364
- <p class="run"><span class="n"><a id="t282" href="#t282">282</a></span><span class="t"> <span class="key">if</span> <span class="nam">param_schema</span><span class="op">:</span>&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"># Clean the schema to remove problematic objects</span>&nbsp;</span><span class="r"></span></p>
366
- <p class="run"><span class="n"><a id="t284" href="#t284">284</a></span><span class="t"> <span class="nam">cleaned_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_clean_schema</span><span class="op">(</span><span class="nam">param_schema</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
367
- <p class="run"><span class="n"><a id="t285" href="#t285">285</a></span><span class="t"> <span class="key">if</span> <span class="nam">cleaned_schema</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
368
- <p class="run"><span class="n"><a id="t286" href="#t286">286</a></span><span class="t"> <span class="nam">properties</span><span class="op">[</span><span class="nam">param_name</span><span class="op">]</span> <span class="op">=</span> <span class="nam">cleaned_schema</span>&nbsp;</span><span class="r"></span></p>
369
- <p class="pln"><span class="n"><a id="t287" href="#t287">287</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
370
- <p class="pln"><span class="n"><a id="t288" href="#t288">288</a></span><span class="t"> <span class="com"># Check if required (no default value)</span>&nbsp;</span><span class="r"></span></p>
371
- <p class="run"><span class="n"><a id="t289" href="#t289">289</a></span><span class="t"> <span class="key">if</span> <span class="nam">param</span><span class="op">.</span><span class="nam">default</span> <span class="key">is</span> <span class="nam">param</span><span class="op">.</span><span class="nam">empty</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
372
- <p class="run"><span class="n"><a id="t290" href="#t290">290</a></span><span class="t"> <span class="nam">required</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">param_name</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="run"><span class="n"><a id="t292" href="#t292">292</a></span><span class="t"> <span class="key">if</span> <span class="nam">properties</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
375
- <p class="run"><span class="n"><a id="t293" href="#t293">293</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
376
- <p class="pln"><span class="n"><a id="t294" href="#t294">294</a></span><span class="t"> <span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
377
- <p class="pln"><span class="n"><a id="t295" href="#t295">295</a></span><span class="t"> <span class="str">"properties"</span><span class="op">:</span> <span class="nam">properties</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
378
- <p class="pln"><span class="n"><a id="t296" href="#t296">296</a></span><span class="t"> <span class="str">"required"</span><span class="op">:</span> <span class="nam">required</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"> <span class="op">}</span>&nbsp;</span><span class="r"></span></p>
380
- <p class="pln"><span class="n"><a id="t298" href="#t298">298</a></span><span class="t">&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">console</span><span class="op">.</span><span class="nam">print</span><span class="op">(</span><span class="str">f"[yellow]Warning: Could not extract input schema: {e}[/yellow]"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
383
- <p class="pln"><span class="n"><a id="t301" href="#t301">301</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
384
- <p class="run"><span class="n"><a id="t302" href="#t302">302</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span>&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">&nbsp;</span><span class="r"></span></p>
386
- <p class="run"><span class="n"><a id="t304" href="#t304">304</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_output_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">func</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
387
- <p class="pln"><span class="n"><a id="t305" href="#t305">305</a></span><span class="t"> <span class="str">"""Extract output schema from return type annotation."""</span>&nbsp;</span><span class="r"></span></p>
388
- <p class="run"><span class="n"><a id="t306" href="#t306">306</a></span><span class="t"> <span class="key">from</span> <span class="nam">typing</span> <span class="key">import</span> <span class="nam">get_type_hints</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">&nbsp;</span><span class="r"></span></p>
390
- <p class="run"><span class="n"><a id="t308" href="#t308">308</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
391
- <p class="run"><span class="n"><a id="t309" href="#t309">309</a></span><span class="t"> <span class="nam">type_hints</span> <span class="op">=</span> <span class="nam">get_type_hints</span><span class="op">(</span><span class="nam">func</span><span class="op">,</span> <span class="nam">include_extras</span><span class="op">=</span><span class="key">True</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
392
- <p class="run"><span class="n"><a id="t310" href="#t310">310</a></span><span class="t"> <span class="nam">return_type</span> <span class="op">=</span> <span class="nam">type_hints</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"return"</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">&nbsp;</span><span class="r"></span></p>
394
- <p class="run"><span class="n"><a id="t312" href="#t312">312</a></span><span class="t"> <span class="key">if</span> <span class="nam">return_type</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
395
- <p class="mis show_mis"><span class="n"><a id="t313" href="#t313">313</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
396
- <p class="pln"><span class="n"><a id="t314" href="#t314">314</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
397
- <p class="pln"><span class="n"><a id="t315" href="#t315">315</a></span><span class="t"> <span class="com"># If it's a Pydantic BaseModel, extract schema manually</span>&nbsp;</span><span class="r"></span></p>
398
- <p class="run"><span class="n"><a id="t316" href="#t316">316</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">return_type</span><span class="op">,</span> <span class="str">"model_fields"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
399
- <p class="run"><span class="n"><a id="t317" href="#t317">317</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_pydantic_model_schema</span><span class="op">(</span><span class="nam">return_type</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
400
- <p class="pln"><span class="n"><a id="t318" href="#t318">318</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
401
- <p class="pln"><span class="n"><a id="t319" href="#t319">319</a></span><span class="t"> <span class="com"># For other types, create a simple schema</span>&nbsp;</span><span class="r"></span></p>
402
- <p class="run"><span class="n"><a id="t320" href="#t320">320</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_to_schema</span><span class="op">(</span><span class="nam">return_type</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">&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">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>
405
- <p class="mis show_mis"><span class="n"><a id="t323" href="#t323">323</a></span><span class="t"> <span class="nam">console</span><span class="op">.</span><span class="nam">print</span><span class="op">(</span><span class="str">f"[yellow]Warning: Could not extract output schema: {e}[/yellow]"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
406
- <p class="pln"><span class="n"><a id="t324" href="#t324">324</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
407
- <p class="mis show_mis"><span class="n"><a id="t325" href="#t325">325</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
408
- <p class="pln"><span class="n"><a id="t326" href="#t326">326</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
409
- <p class="run"><span class="n"><a id="t327" href="#t327">327</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_pydantic_model_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">model_class</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</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="str">"""Extract schema from Pydantic model by inspecting fields directly."""</span>&nbsp;</span><span class="r"></span></p>
411
- <p class="run"><span class="n"><a id="t329" href="#t329">329</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
412
- <p class="run"><span class="n"><a id="t330" href="#t330">330</a></span><span class="t"> <span class="nam">schema</span> <span class="op">=</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">,</span> <span class="str">"properties"</span><span class="op">:</span> <span class="op">{</span><span class="op">}</span><span class="op">,</span> <span class="str">"required"</span><span class="op">:</span> <span class="op">[</span><span class="op">]</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
413
- <p class="pln"><span class="n"><a id="t331" href="#t331">331</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
414
- <p class="run"><span class="n"><a id="t332" href="#t332">332</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">model_class</span><span class="op">,</span> <span class="str">"model_fields"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
415
- <p class="run"><span class="n"><a id="t333" href="#t333">333</a></span><span class="t"> <span class="key">for</span> <span class="nam">field_name</span><span class="op">,</span> <span class="nam">field_info</span> <span class="key">in</span> <span class="nam">model_class</span><span class="op">.</span><span class="nam">model_fields</span><span class="op">.</span><span class="nam">items</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
416
- <p class="pln"><span class="n"><a id="t334" href="#t334">334</a></span><span class="t"> <span class="com"># Extract field type</span>&nbsp;</span><span class="r"></span></p>
417
- <p class="run"><span class="n"><a id="t335" href="#t335">335</a></span><span class="t"> <span class="nam">field_type</span> <span class="op">=</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">annotation</span> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">field_info</span><span class="op">,</span> <span class="str">"annotation"</span><span class="op">)</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
418
- <p class="run"><span class="n"><a id="t336" href="#t336">336</a></span><span class="t"> <span class="key">if</span> <span class="nam">field_type</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
419
- <p class="run"><span class="n"><a id="t337" href="#t337">337</a></span><span class="t"> <span class="nam">field_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_to_schema</span><span class="op">(</span><span class="nam">field_type</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">&nbsp;</span><span class="r"></span></p>
421
- <p class="pln"><span class="n"><a id="t339" href="#t339">339</a></span><span class="t"> <span class="com"># Add description if available</span>&nbsp;</span><span class="r"></span></p>
422
- <p class="run"><span class="n"><a id="t340" href="#t340">340</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">field_info</span><span class="op">,</span> <span class="str">"description"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">description</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">field_schema</span><span class="op">[</span><span class="str">"description"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">description</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">&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="com"># Add title</span>&nbsp;</span><span class="r"></span></p>
426
- <p class="run"><span class="n"><a id="t344" href="#t344">344</a></span><span class="t"> <span class="nam">field_schema</span><span class="op">[</span><span class="str">"title"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">field_name</span><span class="op">.</span><span class="nam">replace</span><span class="op">(</span><span class="str">"_"</span><span class="op">,</span> <span class="str">" "</span><span class="op">)</span><span class="op">.</span><span class="nam">title</span><span class="op">(</span><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 default if available</span>&nbsp;</span><span class="r"></span></p>
429
- <p class="run"><span class="n"><a id="t347" href="#t347">347</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">field_info</span><span class="op">,</span> <span class="str">"default"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">default</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>
430
- <p class="run"><span class="n"><a id="t348" href="#t348">348</a></span><span class="t"> <span class="key">try</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"> <span class="com"># Only add if it's JSON serializable</span>&nbsp;</span><span class="r"></span></p>
432
- <p class="run"><span class="n"><a id="t350" href="#t350">350</a></span><span class="t"> <span class="key">import</span> <span class="nam">json</span>&nbsp;</span><span class="r"></span></p>
433
- <p class="pln"><span class="n"><a id="t351" href="#t351">351</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
434
- <p class="run"><span class="n"><a id="t352" href="#t352">352</a></span><span class="t"> <span class="nam">json</span><span class="op">.</span><span class="nam">dumps</span><span class="op">(</span><span class="nam">field_info</span><span class="op">.</span><span class="nam">default</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
435
- <p class="mis show_mis"><span class="n"><a id="t353" href="#t353">353</a></span><span class="t"> <span class="nam">field_schema</span><span class="op">[</span><span class="str">"default"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">default</span>&nbsp;</span><span class="r"></span></p>
436
- <p class="run"><span class="n"><a id="t354" href="#t354">354</a></span><span class="t"> <span class="key">except</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
437
- <p class="run"><span class="n"><a id="t355" href="#t355">355</a></span><span class="t"> <span class="key">pass</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">&nbsp;</span><span class="r"></span></p>
439
- <p class="run"><span class="n"><a id="t357" href="#t357">357</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"properties"</span><span class="op">]</span><span class="op">[</span><span class="nam">field_name</span><span class="op">]</span> <span class="op">=</span> <span class="nam">field_schema</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">&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="com"># Check if required</span>&nbsp;</span><span class="r"></span></p>
442
- <p class="run"><span class="n"><a id="t360" href="#t360">360</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">field_info</span><span class="op">,</span> <span class="str">"is_required"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">is_required</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
443
- <p class="run"><span class="n"><a id="t361" href="#t361">361</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"required"</span><span class="op">]</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">field_name</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">elif</span> <span class="key">not</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">field_info</span><span class="op">,</span> <span class="str">"default"</span><span class="op">)</span> <span class="key">or</span> <span class="nam">field_info</span><span class="op">.</span><span class="nam">default</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
445
- <p class="pln"><span class="n"><a id="t363" href="#t363">363</a></span><span class="t"> <span class="com"># Assume required if no default</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="nam">schema</span><span class="op">[</span><span class="str">"required"</span><span class="op">]</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">field_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
447
- <p class="pln"><span class="n"><a id="t365" href="#t365">365</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
448
- <p class="run"><span class="n"><a id="t366" href="#t366">366</a></span><span class="t"> <span class="key">return</span> <span class="nam">schema</span>&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">&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="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>
451
- <p class="mis show_mis"><span class="n"><a id="t369" href="#t369">369</a></span><span class="t"> <span class="nam">console</span><span class="op">.</span><span class="nam">print</span><span class="op">(</span><span class="str">f"[yellow]Warning: Could not extract Pydantic model schema: {e}[/yellow]"</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="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</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="run"><span class="n"><a id="t372" href="#t372">372</a></span><span class="t"> <span class="key">def</span> <span class="nam">_clean_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">schema</span><span class="op">:</span> <span class="nam">Any</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
455
- <p class="pln"><span class="n"><a id="t373" href="#t373">373</a></span><span class="t"> <span class="str">"""Clean up a schema to remove non-JSON-serializable objects."""</span>&nbsp;</span><span class="r"></span></p>
456
- <p class="run"><span class="n"><a id="t374" href="#t374">374</a></span><span class="t"> <span class="key">import</span> <span class="nam">json</span>&nbsp;</span><span class="r"></span></p>
457
- <p class="pln"><span class="n"><a id="t375" href="#t375">375</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
458
- <p class="run"><span class="n"><a id="t376" href="#t376">376</a></span><span class="t"> <span class="key">def</span> <span class="nam">clean_object</span><span class="op">(</span><span class="nam">obj</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>
459
- <p class="run"><span class="n"><a id="t377" href="#t377">377</a></span><span class="t"> <span class="key">if</span> <span class="nam">obj</span> <span class="key">is</span> <span class="key">None</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
460
- <p class="mis show_mis"><span class="n"><a id="t378" href="#t378">378</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
461
- <p class="run"><span class="n"><a id="t379" href="#t379">379</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">obj</span><span class="op">,</span> <span class="op">(</span><span class="nam">str</span><span class="op">,</span> <span class="nam">int</span><span class="op">,</span> <span class="nam">float</span><span class="op">,</span> <span class="nam">bool</span><span class="op">)</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
462
- <p class="run"><span class="n"><a id="t380" href="#t380">380</a></span><span class="t"> <span class="key">return</span> <span class="nam">obj</span>&nbsp;</span><span class="r"></span></p>
463
- <p class="run"><span class="n"><a id="t381" href="#t381">381</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">obj</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>
464
- <p class="run"><span class="n"><a id="t382" href="#t382">382</a></span><span class="t"> <span class="nam">cleaned</span> <span class="op">=</span> <span class="op">{</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
465
- <p class="run"><span class="n"><a id="t383" href="#t383">383</a></span><span class="t"> <span class="key">for</span> <span class="nam">k</span><span class="op">,</span> <span class="nam">v</span> <span class="key">in</span> <span class="nam">obj</span><span class="op">.</span><span class="nam">items</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
466
- <p class="pln"><span class="n"><a id="t384" href="#t384">384</a></span><span class="t"> <span class="com"># Skip problematic keys</span>&nbsp;</span><span class="r"></span></p>
467
- <p class="run"><span class="n"><a id="t385" href="#t385">385</a></span><span class="t"> <span class="key">if</span> <span class="nam">k</span> <span class="key">in</span> <span class="op">[</span><span class="str">"definitions"</span><span class="op">,</span> <span class="str">"$defs"</span><span class="op">,</span> <span class="str">"allOf"</span><span class="op">,</span> <span class="str">"anyOf"</span><span class="op">,</span> <span class="str">"oneOf"</span><span class="op">]</span><span class="op">:</span>&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="key">continue</span>&nbsp;</span><span class="r"></span></p>
469
- <p class="run"><span class="n"><a id="t387" href="#t387">387</a></span><span class="t"> <span class="nam">cleaned_v</span> <span class="op">=</span> <span class="nam">clean_object</span><span class="op">(</span><span class="nam">v</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
470
- <p class="run"><span class="n"><a id="t388" href="#t388">388</a></span><span class="t"> <span class="key">if</span> <span class="nam">cleaned_v</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>
471
- <p class="run"><span class="n"><a id="t389" href="#t389">389</a></span><span class="t"> <span class="nam">cleaned</span><span class="op">[</span><span class="nam">k</span><span class="op">]</span> <span class="op">=</span> <span class="nam">cleaned_v</span>&nbsp;</span><span class="r"></span></p>
472
- <p class="run"><span class="n"><a id="t390" href="#t390">390</a></span><span class="t"> <span class="key">return</span> <span class="nam">cleaned</span> <span class="key">if</span> <span class="nam">cleaned</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
473
- <p class="run"><span class="n"><a id="t391" href="#t391">391</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">obj</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>
474
- <p class="mis show_mis"><span class="n"><a id="t392" href="#t392">392</a></span><span class="t"> <span class="nam">cleaned</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
475
- <p class="mis show_mis"><span class="n"><a id="t393" href="#t393">393</a></span><span class="t"> <span class="key">for</span> <span class="nam">item</span> <span class="key">in</span> <span class="nam">obj</span><span class="op">:</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="nam">cleaned_item</span> <span class="op">=</span> <span class="nam">clean_object</span><span class="op">(</span><span class="nam">item</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="key">if</span> <span class="nam">cleaned_item</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>
478
- <p class="mis show_mis"><span class="n"><a id="t396" href="#t396">396</a></span><span class="t"> <span class="nam">cleaned</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">cleaned_item</span><span class="op">)</span>&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">return</span> <span class="nam">cleaned</span> <span class="key">if</span> <span class="nam">cleaned</span> <span class="key">else</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
480
- <p class="pln"><span class="n"><a id="t398" href="#t398">398</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
481
- <p class="pln"><span class="n"><a id="t399" href="#t399">399</a></span><span class="t"> <span class="com"># For any other type, test JSON serializability</span>&nbsp;</span><span class="r"></span></p>
482
- <p class="run"><span class="n"><a id="t400" href="#t400">400</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
483
- <p class="run"><span class="n"><a id="t401" href="#t401">401</a></span><span class="t"> <span class="nam">json</span><span class="op">.</span><span class="nam">dumps</span><span class="op">(</span><span class="nam">obj</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
484
- <p class="mis show_mis"><span class="n"><a id="t402" href="#t402">402</a></span><span class="t"> <span class="key">return</span> <span class="nam">obj</span>&nbsp;</span><span class="r"></span></p>
485
- <p class="run"><span class="n"><a id="t403" href="#t403">403</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>
486
- <p class="pln"><span class="n"><a id="t404" href="#t404">404</a></span><span class="t"> <span class="com"># If it's not JSON serializable, try to get a string representation</span>&nbsp;</span><span class="r"></span></p>
487
- <p class="run"><span class="n"><a id="t405" href="#t405">405</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">obj</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>
488
- <p class="mis show_mis"><span class="n"><a id="t406" href="#t406">406</a></span><span class="t"> <span class="key">return</span> <span class="nam">obj</span><span class="op">.</span><span class="nam">__name__</span>&nbsp;</span><span class="r"></span></p>
489
- <p class="run"><span class="n"><a id="t407" href="#t407">407</a></span><span class="t"> <span class="key">elif</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">obj</span><span class="op">,</span> <span class="str">"__str__"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
490
- <p class="run"><span class="n"><a id="t408" href="#t408">408</a></span><span class="t"> <span class="key">try</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
491
- <p class="run"><span class="n"><a id="t409" href="#t409">409</a></span><span class="t"> <span class="nam">str_val</span> <span class="op">=</span> <span class="nam">str</span><span class="op">(</span><span class="nam">obj</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
492
- <p class="run"><span class="n"><a id="t410" href="#t410">410</a></span><span class="t"> <span class="key">if</span> <span class="nam">str_val</span> <span class="key">and</span> <span class="nam">str_val</span> <span class="op">!=</span> <span class="nam">repr</span><span class="op">(</span><span class="nam">obj</span><span class="op">)</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="key">return</span> <span class="nam">str_val</span>&nbsp;</span><span class="r"></span></p>
494
- <p class="mis show_mis"><span class="n"><a id="t412" href="#t412">412</a></span><span class="t"> <span class="key">except</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
495
- <p class="mis show_mis"><span class="n"><a id="t413" href="#t413">413</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
496
- <p class="run"><span class="n"><a id="t414" href="#t414">414</a></span><span class="t"> <span class="key">return</span> <span class="key">None</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">&nbsp;</span><span class="r"></span></p>
498
- <p class="run"><span class="n"><a id="t416" href="#t416">416</a></span><span class="t"> <span class="nam">cleaned</span> <span class="op">=</span> <span class="nam">clean_object</span><span class="op">(</span><span class="nam">schema</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
499
- <p class="run"><span class="n"><a id="t417" href="#t417">417</a></span><span class="t"> <span class="key">return</span> <span class="nam">cleaned</span> <span class="key">if</span> <span class="nam">cleaned</span> <span class="key">else</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</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">&nbsp;</span><span class="r"></span></p>
501
- <p class="run"><span class="n"><a id="t419" href="#t419">419</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_param_schema_from_hint</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">type_hint</span><span class="op">:</span> <span class="nam">Any</span><span class="op">,</span> <span class="nam">param_name</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
502
- <p class="pln"><span class="n"><a id="t420" href="#t420">420</a></span><span class="t"> <span class="str">"""Extract parameter schema from type hint (including Annotated types)."""</span>&nbsp;</span><span class="r"></span></p>
503
- <p class="run"><span class="n"><a id="t421" href="#t421">421</a></span><span class="t"> <span class="key">from</span> <span class="nam">typing</span> <span class="key">import</span> <span class="nam">get_args</span><span class="op">,</span> <span class="nam">get_origin</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"># Handle Annotated types</span>&nbsp;</span><span class="r"></span></p>
506
- <p class="run"><span class="n"><a id="t424" href="#t424">424</a></span><span class="t"> <span class="key">if</span> <span class="nam">get_origin</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">)</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>
507
- <p class="run"><span class="n"><a id="t425" href="#t425">425</a></span><span class="t"> <span class="nam">origin</span> <span class="op">=</span> <span class="nam">get_origin</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
508
- <p class="run"><span class="n"><a id="t426" href="#t426">426</a></span><span class="t"> <span class="nam">args</span> <span class="op">=</span> <span class="nam">get_args</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
509
- <p class="pln"><span class="n"><a id="t427" href="#t427">427</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
510
- <p class="pln"><span class="n"><a id="t428" href="#t428">428</a></span><span class="t"> <span class="com"># Check for Annotated[Type, Field(...)]</span>&nbsp;</span><span class="r"></span></p>
511
- <p class="run"><span class="n"><a id="t429" href="#t429">429</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">origin</span><span class="op">,</span> <span class="str">"__name__"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">origin</span><span class="op">.</span><span class="nam">__name__</span> <span class="op">==</span> <span class="str">"Annotated"</span> <span class="key">and</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">2</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
512
- <p class="run"><span class="n"><a id="t430" href="#t430">430</a></span><span class="t"> <span class="nam">base_type</span> <span class="op">=</span> <span class="nam">args</span><span class="op">[</span><span class="num">0</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
513
- <p class="run"><span class="n"><a id="t431" href="#t431">431</a></span><span class="t"> <span class="nam">metadata</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="op">]</span>&nbsp;</span><span class="r"></span></p>
514
- <p class="pln"><span class="n"><a id="t432" href="#t432">432</a></span><span class="t">&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"> <span class="com"># Start with base type schema</span>&nbsp;</span><span class="r"></span></p>
516
- <p class="run"><span class="n"><a id="t434" href="#t434">434</a></span><span class="t"> <span class="nam">schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_to_schema</span><span class="op">(</span><span class="nam">base_type</span><span class="op">)</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"># Extract Field metadata</span>&nbsp;</span><span class="r"></span></p>
519
- <p class="run"><span class="n"><a id="t437" href="#t437">437</a></span><span class="t"> <span class="key">for</span> <span class="nam">meta</span> <span class="key">in</span> <span class="nam">metadata</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
520
- <p class="run"><span class="n"><a id="t438" href="#t438">438</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">meta</span><span class="op">,</span> <span class="str">"description"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">meta</span><span class="op">.</span><span class="nam">description</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
521
- <p class="run"><span class="n"><a id="t439" href="#t439">439</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"description"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">meta</span><span class="op">.</span><span class="nam">description</span>&nbsp;</span><span class="r"></span></p>
522
- <p class="run"><span class="n"><a id="t440" href="#t440">440</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">meta</span><span class="op">,</span> <span class="str">"title"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">meta</span><span class="op">.</span><span class="nam">title</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
523
- <p class="mis show_mis"><span class="n"><a id="t441" href="#t441">441</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"title"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">meta</span><span class="op">.</span><span class="nam">title</span>&nbsp;</span><span class="r"></span></p>
524
- <p class="run"><span class="n"><a id="t442" href="#t442">442</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">meta</span><span class="op">,</span> <span class="str">"default"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">meta</span><span class="op">.</span><span class="nam">default</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>
525
- <p class="run"><span class="n"><a id="t443" href="#t443">443</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"default"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">meta</span><span class="op">.</span><span class="nam">default</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="com"># Add other Field constraints as needed</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">&nbsp;</span><span class="r"></span></p>
528
- <p class="run"><span class="n"><a id="t446" href="#t446">446</a></span><span class="t"> <span class="key">return</span> <span class="nam">schema</span>&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">&nbsp;</span><span class="r"></span></p>
530
- <p class="pln"><span class="n"><a id="t448" href="#t448">448</a></span><span class="t"> <span class="com"># For non-Annotated types, just convert the type</span>&nbsp;</span><span class="r"></span></p>
531
- <p class="run"><span class="n"><a id="t449" href="#t449">449</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_to_schema</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">)</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="run"><span class="n"><a id="t451" href="#t451">451</a></span><span class="t"> <span class="key">def</span> <span class="nam">_type_to_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">type_hint</span><span class="op">:</span> <span class="nam">object</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</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"> <span class="str">"""Convert a Python type to JSON schema."""</span>&nbsp;</span><span class="r"></span></p>
535
- <p class="run"><span class="n"><a id="t453" href="#t453">453</a></span><span class="t"> <span class="key">from</span> <span class="nam">typing</span> <span class="key">import</span> <span class="nam">get_args</span><span class="op">,</span> <span class="nam">get_origin</span>&nbsp;</span><span class="r"></span></p>
536
- <p class="run"><span class="n"><a id="t454" href="#t454">454</a></span><span class="t"> <span class="key">import</span> <span class="nam">types</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="pln"><span class="n"><a id="t456" href="#t456">456</a></span><span class="t"> <span class="com"># Handle None/NoneType</span>&nbsp;</span><span class="r"></span></p>
539
- <p class="run"><span class="n"><a id="t457" href="#t457">457</a></span><span class="t"> <span class="key">if</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">type</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>
540
- <p class="mis show_mis"><span class="n"><a id="t458" href="#t458">458</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"null"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
541
- <p class="pln"><span class="n"><a id="t459" href="#t459">459</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
542
- <p class="pln"><span class="n"><a id="t460" href="#t460">460</a></span><span class="t"> <span class="com"># Handle basic types</span>&nbsp;</span><span class="r"></span></p>
543
- <p class="run"><span class="n"><a id="t461" href="#t461">461</a></span><span class="t"> <span class="key">if</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">str</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
544
- <p class="run"><span class="n"><a id="t462" href="#t462">462</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"string"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
545
- <p class="run"><span class="n"><a id="t463" href="#t463">463</a></span><span class="t"> <span class="key">elif</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">int</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
546
- <p class="run"><span class="n"><a id="t464" href="#t464">464</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"integer"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
547
- <p class="run"><span class="n"><a id="t465" href="#t465">465</a></span><span class="t"> <span class="key">elif</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">float</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
548
- <p class="mis show_mis"><span class="n"><a id="t466" href="#t466">466</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"number"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
549
- <p class="run"><span class="n"><a id="t467" href="#t467">467</a></span><span class="t"> <span class="key">elif</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">bool</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
550
- <p class="run"><span class="n"><a id="t468" href="#t468">468</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"boolean"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
551
- <p class="run"><span class="n"><a id="t469" href="#t469">469</a></span><span class="t"> <span class="key">elif</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">list</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
552
- <p class="run"><span class="n"><a id="t470" href="#t470">470</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
553
- <p class="run"><span class="n"><a id="t471" href="#t471">471</a></span><span class="t"> <span class="key">elif</span> <span class="nam">type_hint</span> <span class="key">is</span> <span class="nam">dict</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
554
- <p class="run"><span class="n"><a id="t472" href="#t472">472</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</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">&nbsp;</span><span class="r"></span></p>
556
- <p class="pln"><span class="n"><a id="t474" href="#t474">474</a></span><span class="t"> <span class="com"># Handle generic types</span>&nbsp;</span><span class="r"></span></p>
557
- <p class="mis show_mis"><span class="n"><a id="t475" href="#t475">475</a></span><span class="t"> <span class="nam">origin</span> <span class="op">=</span> <span class="nam">get_origin</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
558
- <p class="mis show_mis"><span class="n"><a id="t476" href="#t476">476</a></span><span class="t"> <span class="key">if</span> <span class="nam">origin</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>
559
- <p class="mis show_mis"><span class="n"><a id="t477" href="#t477">477</a></span><span class="t"> <span class="nam">args</span> <span class="op">=</span> <span class="nam">get_args</span><span class="op">(</span><span class="nam">type_hint</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">&nbsp;</span><span class="r"></span></p>
561
- <p class="mis show_mis"><span class="n"><a id="t479" href="#t479">479</a></span><span class="t"> <span class="key">if</span> <span class="nam">origin</span> <span class="key">is</span> <span class="nam">list</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
562
- <p class="mis show_mis"><span class="n"><a id="t480" href="#t480">480</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>
563
- <p class="mis show_mis"><span class="n"><a id="t481" href="#t481">481</a></span><span class="t"> <span class="nam">item_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_to_schema</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>&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">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">,</span> <span class="str">"items"</span><span class="op">:</span> <span class="nam">item_schema</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="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
566
- <p class="pln"><span class="n"><a id="t484" href="#t484">484</a></span><span class="t">&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="key">elif</span> <span class="nam">origin</span> <span class="key">is</span> <span class="nam">dict</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
568
- <p class="mis show_mis"><span class="n"><a id="t486" href="#t486">486</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">}</span>&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">&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="key">elif</span> <span class="op">(</span>&nbsp;</span><span class="r"></span></p>
571
- <p class="pln"><span class="n"><a id="t489" href="#t489">489</a></span><span class="t"> <span class="nam">origin</span> <span class="key">is</span> <span class="nam">types</span><span class="op">.</span><span class="nam">UnionType</span>&nbsp;</span><span class="r"></span></p>
572
- <p class="pln"><span class="n"><a id="t490" href="#t490">490</a></span><span class="t"> <span class="key">or</span> <span class="op">(</span><span class="nam">hasattr</span><span class="op">(</span><span class="nam">types</span><span class="op">,</span> <span class="str">"UnionType"</span><span class="op">)</span> <span class="key">and</span> <span class="nam">origin</span> <span class="key">is</span> <span class="nam">types</span><span class="op">.</span><span class="nam">UnionType</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"> <span class="key">or</span> <span class="nam">str</span><span class="op">(</span><span class="nam">origin</span><span class="op">)</span><span class="op">.</span><span class="nam">startswith</span><span class="op">(</span><span class="str">"typing.Union"</span><span class="op">)</span>&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="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
575
- <p class="pln"><span class="n"><a id="t493" href="#t493">493</a></span><span class="t"> <span class="com"># Handle Union types (including Optional)</span>&nbsp;</span><span class="r"></span></p>
576
- <p class="mis show_mis"><span class="n"><a id="t494" href="#t494">494</a></span><span class="t"> <span class="nam">non_none_types</span> <span class="op">=</span> <span class="op">[</span><span class="nam">arg</span> <span class="key">for</span> <span class="nam">arg</span> <span class="key">in</span> <span class="nam">args</span> <span class="key">if</span> <span class="nam">arg</span> <span class="key">is</span> <span class="key">not</span> <span class="nam">type</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>
577
- <p class="mis show_mis"><span class="n"><a id="t495" href="#t495">495</a></span><span class="t"> <span class="key">if</span> <span class="nam">len</span><span class="op">(</span><span class="nam">non_none_types</span><span class="op">)</span> <span class="op">==</span> <span class="num">1</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
578
- <p class="pln"><span class="n"><a id="t496" href="#t496">496</a></span><span class="t"> <span class="com"># This is Optional[Type]</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="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_to_schema</span><span class="op">(</span><span class="nam">non_none_types</span><span class="op">[</span><span class="num">0</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"> <span class="com"># For complex unions, default to object</span>&nbsp;</span><span class="r"></span></p>
581
- <p class="mis show_mis"><span class="n"><a id="t499" href="#t499">499</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
582
- <p class="pln"><span class="n"><a id="t500" href="#t500">500</a></span><span class="t">&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"> <span class="com"># For unknown types, try to use Pydantic schema if available</span>&nbsp;</span><span class="r"></span></p>
584
- <p class="mis show_mis"><span class="n"><a id="t502" href="#t502">502</a></span><span class="t"> <span class="key">if</span> <span class="nam">hasattr</span><span class="op">(</span><span class="nam">type_hint</span><span class="op">,</span> <span class="str">"model_json_schema"</span><span class="op">)</span><span class="op">:</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="nam">schema</span> <span class="op">=</span> <span class="nam">type_hint</span><span class="op">.</span><span class="nam">model_json_schema</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="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_clean_schema</span><span class="op">(</span><span class="nam">schema</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"># Default fallback</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">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
590
- <p class="pln"><span class="n"><a id="t508" href="#t508">508</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
591
- <p class="run"><span class="n"><a id="t509" href="#t509">509</a></span><span class="t"> <span class="key">def</span> <span class="nam">_process_tool</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">component</span><span class="op">:</span> <span class="nam">ParsedComponent</span><span class="op">,</span> <span class="nam">tree</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Module</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>
592
- <p class="pln"><span class="n"><a id="t510" href="#t510">510</a></span><span class="t"> <span class="str">"""Process a tool component to extract input/output schemas and annotations."""</span>&nbsp;</span><span class="r"></span></p>
593
- <p class="pln"><span class="n"><a id="t511" href="#t511">511</a></span><span class="t"> <span class="com"># Look for Input and Output classes in the AST</span>&nbsp;</span><span class="r"></span></p>
594
- <p class="run"><span class="n"><a id="t512" href="#t512">512</a></span><span class="t"> <span class="nam">input_class</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
595
- <p class="run"><span class="n"><a id="t513" href="#t513">513</a></span><span class="t"> <span class="nam">output_class</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
596
- <p class="run"><span class="n"><a id="t514" href="#t514">514</a></span><span class="t"> <span class="nam">annotations</span> <span class="op">=</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
597
- <p class="pln"><span class="n"><a id="t515" href="#t515">515</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
598
- <p class="run"><span class="n"><a id="t516" href="#t516">516</a></span><span class="t"> <span class="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">tree</span><span class="op">.</span><span class="nam">body</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
599
- <p class="run"><span class="n"><a id="t517" href="#t517">517</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">ClassDef</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
600
- <p class="run"><span class="n"><a id="t518" href="#t518">518</a></span><span class="t"> <span class="key">if</span> <span class="nam">node</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="str">"Input"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
601
- <p class="run"><span class="n"><a id="t519" href="#t519">519</a></span><span class="t"> <span class="nam">input_class</span> <span class="op">=</span> <span class="nam">node</span>&nbsp;</span><span class="r"></span></p>
602
- <p class="run"><span class="n"><a id="t520" href="#t520">520</a></span><span class="t"> <span class="key">elif</span> <span class="nam">node</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="str">"Output"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
603
- <p class="run"><span class="n"><a id="t521" href="#t521">521</a></span><span class="t"> <span class="nam">output_class</span> <span class="op">=</span> <span class="nam">node</span>&nbsp;</span><span class="r"></span></p>
604
- <p class="pln"><span class="n"><a id="t522" href="#t522">522</a></span><span class="t"> <span class="com"># Look for annotations assignment</span>&nbsp;</span><span class="r"></span></p>
605
- <p class="run"><span class="n"><a id="t523" href="#t523">523</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Assign</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
606
- <p class="run"><span class="n"><a id="t524" href="#t524">524</a></span><span class="t"> <span class="key">for</span> <span class="nam">target</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">targets</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
607
- <p class="run"><span class="n"><a id="t525" href="#t525">525</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">target</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span> <span class="key">and</span> <span class="nam">target</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"annotations"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
608
- <p class="run"><span class="n"><a id="t526" href="#t526">526</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</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>
609
- <p class="run"><span class="n"><a id="t527" href="#t527">527</a></span><span class="t"> <span class="nam">annotations</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_dict_from_ast</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
610
- <p class="run"><span class="n"><a id="t528" href="#t528">528</a></span><span class="t"> <span class="key">break</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">&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="com"># Process Input class if found</span>&nbsp;</span><span class="r"></span></p>
613
- <p class="run"><span class="n"><a id="t531" href="#t531">531</a></span><span class="t"> <span class="key">if</span> <span class="nam">input_class</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="com"># Check if it inherits from BaseModel</span>&nbsp;</span><span class="r"></span></p>
615
- <p class="run"><span class="n"><a id="t533" href="#t533">533</a></span><span class="t"> <span class="key">for</span> <span class="nam">base</span> <span class="key">in</span> <span class="nam">input_class</span><span class="op">.</span><span class="nam">bases</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
616
- <p class="run"><span class="n"><a id="t534" href="#t534">534</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">base</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span> <span class="key">and</span> <span class="nam">base</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"BaseModel"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
617
- <p class="run"><span class="n"><a id="t535" href="#t535">535</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">input_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_pydantic_schema_from_ast</span><span class="op">(</span><span class="nam">input_class</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
618
- <p class="run"><span class="n"><a id="t536" href="#t536">536</a></span><span class="t"> <span class="key">break</span>&nbsp;</span><span class="r"></span></p>
619
- <p class="pln"><span class="n"><a id="t537" href="#t537">537</a></span><span class="t">&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"># Process Output class if found</span>&nbsp;</span><span class="r"></span></p>
621
- <p class="run"><span class="n"><a id="t539" href="#t539">539</a></span><span class="t"> <span class="key">if</span> <span class="nam">output_class</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
622
- <p class="pln"><span class="n"><a id="t540" href="#t540">540</a></span><span class="t"> <span class="com"># Check if it inherits from BaseModel</span>&nbsp;</span><span class="r"></span></p>
623
- <p class="run"><span class="n"><a id="t541" href="#t541">541</a></span><span class="t"> <span class="key">for</span> <span class="nam">base</span> <span class="key">in</span> <span class="nam">output_class</span><span class="op">.</span><span class="nam">bases</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
624
- <p class="run"><span class="n"><a id="t542" href="#t542">542</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">base</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span> <span class="key">and</span> <span class="nam">base</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"BaseModel"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
625
- <p class="run"><span class="n"><a id="t543" href="#t543">543</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">output_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_pydantic_schema_from_ast</span><span class="op">(</span><span class="nam">output_class</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
626
- <p class="run"><span class="n"><a id="t544" href="#t544">544</a></span><span class="t"> <span class="key">break</span>&nbsp;</span><span class="r"></span></p>
627
- <p class="pln"><span class="n"><a id="t545" href="#t545">545</a></span><span class="t">&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="com"># Store annotations if found</span>&nbsp;</span><span class="r"></span></p>
629
- <p class="run"><span class="n"><a id="t547" href="#t547">547</a></span><span class="t"> <span class="key">if</span> <span class="nam">annotations</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
630
- <p class="run"><span class="n"><a id="t548" href="#t548">548</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">annotations</span> <span class="op">=</span> <span class="nam">annotations</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="run"><span class="n"><a id="t550" href="#t550">550</a></span><span class="t"> <span class="key">def</span> <span class="nam">_process_resource</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">component</span><span class="op">:</span> <span class="nam">ParsedComponent</span><span class="op">,</span> <span class="nam">tree</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Module</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>
633
- <p class="pln"><span class="n"><a id="t551" href="#t551">551</a></span><span class="t"> <span class="str">"""Process a resource component to extract URI template."""</span>&nbsp;</span><span class="r"></span></p>
634
- <p class="pln"><span class="n"><a id="t552" href="#t552">552</a></span><span class="t"> <span class="com"># Look for resource_uri assignment in the AST</span>&nbsp;</span><span class="r"></span></p>
635
- <p class="run"><span class="n"><a id="t553" href="#t553">553</a></span><span class="t"> <span class="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">tree</span><span class="op">.</span><span class="nam">body</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
636
- <p class="run"><span class="n"><a id="t554" href="#t554">554</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Assign</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
637
- <p class="run"><span class="n"><a id="t555" href="#t555">555</a></span><span class="t"> <span class="key">for</span> <span class="nam">target</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">targets</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
638
- <p class="run"><span class="n"><a id="t556" href="#t556">556</a></span><span class="t"> <span class="key">if</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="nam">isinstance</span><span class="op">(</span><span class="nam">target</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</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="key">and</span> <span class="nam">target</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"resource_uri"</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="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</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><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
643
- <p class="run"><span class="n"><a id="t561" href="#t561">561</a></span><span class="t"> <span class="nam">uri_template</span> <span class="op">=</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
644
- <p class="run"><span class="n"><a id="t562" href="#t562">562</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">uri_template</span> <span class="op">=</span> <span class="nam">uri_template</span>&nbsp;</span><span class="r"></span></p>
645
- <p class="pln"><span class="n"><a id="t563" href="#t563">563</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
646
- <p class="pln"><span class="n"><a id="t564" href="#t564">564</a></span><span class="t"> <span class="com"># Extract URI parameters (parts in {})</span>&nbsp;</span><span class="r"></span></p>
647
- <p class="run"><span class="n"><a id="t565" href="#t565">565</a></span><span class="t"> <span class="nam">uri_params</span> <span class="op">=</span> <span class="nam">re</span><span class="op">.</span><span class="nam">findall</span><span class="op">(</span><span class="str">r"{([^}]+)}"</span><span class="op">,</span> <span class="nam">uri_template</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
648
- <p class="run"><span class="n"><a id="t566" href="#t566">566</a></span><span class="t"> <span class="key">if</span> <span class="nam">uri_params</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
649
- <p class="run"><span class="n"><a id="t567" href="#t567">567</a></span><span class="t"> <span class="nam">component</span><span class="op">.</span><span class="nam">parameters</span> <span class="op">=</span> <span class="nam">uri_params</span>&nbsp;</span><span class="r"></span></p>
650
- <p class="run"><span class="n"><a id="t568" href="#t568">568</a></span><span class="t"> <span class="key">break</span>&nbsp;</span><span class="r"></span></p>
651
- <p class="pln"><span class="n"><a id="t569" href="#t569">569</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
652
- <p class="run"><span class="n"><a id="t570" href="#t570">570</a></span><span class="t"> <span class="key">def</span> <span class="nam">_process_prompt</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">component</span><span class="op">:</span> <span class="nam">ParsedComponent</span><span class="op">,</span> <span class="nam">tree</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Module</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>
653
- <p class="pln"><span class="n"><a id="t571" href="#t571">571</a></span><span class="t"> <span class="str">"""Process a prompt component (no special processing needed)."""</span>&nbsp;</span><span class="r"></span></p>
654
- <p class="run"><span class="n"><a id="t572" href="#t572">572</a></span><span class="t"> <span class="key">pass</span>&nbsp;</span><span class="r"></span></p>
655
- <p class="pln"><span class="n"><a id="t573" href="#t573">573</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
656
- <p class="run"><span class="n"><a id="t574" href="#t574">574</a></span><span class="t"> <span class="key">def</span> <span class="nam">_derive_component_name</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">file_path</span><span class="op">:</span> <span class="nam">Path</span><span class="op">,</span> <span class="nam">component_type</span><span class="op">:</span> <span class="nam">ComponentType</span><span class="op">)</span> <span class="op">-></span> <span class="nam">str</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
657
- <p class="pln"><span class="n"><a id="t575" href="#t575">575</a></span><span class="t"> <span class="str">"""Derive a component name from its file path according to the spec.</span>&nbsp;</span><span class="r"></span></p>
658
- <p class="pln"><span class="n"><a id="t576" href="#t576">576</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
659
- <p class="pln"><span class="n"><a id="t577" href="#t577">577</a></span><span class="t"><span class="str"> Following the spec: &lt;filename> + ("_" + "_".join(PathRev) if PathRev else "")</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"><span class="str"> where PathRev is the reversed list of parent directories under the category.</span>&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="str"> """</span>&nbsp;</span><span class="r"></span></p>
662
- <p class="run"><span class="n"><a id="t580" href="#t580">580</a></span><span class="t"> <span class="nam">rel_path</span> <span class="op">=</span> <span class="nam">file_path</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">project_root</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"># Find which category directory this is in</span>&nbsp;</span><span class="r"></span></p>
665
- <p class="run"><span class="n"><a id="t583" href="#t583">583</a></span><span class="t"> <span class="nam">category_idx</span> <span class="op">=</span> <span class="op">-</span><span class="num">1</span>&nbsp;</span><span class="r"></span></p>
666
- <p class="run"><span class="n"><a id="t584" href="#t584">584</a></span><span class="t"> <span class="key">for</span> <span class="nam">i</span><span class="op">,</span> <span class="nam">part</span> <span class="key">in</span> <span class="nam">enumerate</span><span class="op">(</span><span class="nam">rel_path</span><span class="op">.</span><span class="nam">parts</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
667
- <p class="run"><span class="n"><a id="t585" href="#t585">585</a></span><span class="t"> <span class="key">if</span> <span class="nam">part</span> <span class="key">in</span> <span class="op">[</span><span class="str">"tools"</span><span class="op">,</span> <span class="str">"resources"</span><span class="op">,</span> <span class="str">"prompts"</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
668
- <p class="run"><span class="n"><a id="t586" href="#t586">586</a></span><span class="t"> <span class="nam">category_idx</span> <span class="op">=</span> <span class="nam">i</span>&nbsp;</span><span class="r"></span></p>
669
- <p class="run"><span class="n"><a id="t587" href="#t587">587</a></span><span class="t"> <span class="key">break</span>&nbsp;</span><span class="r"></span></p>
670
- <p class="pln"><span class="n"><a id="t588" href="#t588">588</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
671
- <p class="run"><span class="n"><a id="t589" href="#t589">589</a></span><span class="t"> <span class="key">if</span> <span class="nam">category_idx</span> <span class="op">==</span> <span class="op">-</span><span class="num">1</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">return</span> <span class="str">""</span>&nbsp;</span><span class="r"></span></p>
673
- <p class="pln"><span class="n"><a id="t591" href="#t591">591</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
674
- <p class="pln"><span class="n"><a id="t592" href="#t592">592</a></span><span class="t"> <span class="com"># Get the filename without extension</span>&nbsp;</span><span class="r"></span></p>
675
- <p class="run"><span class="n"><a id="t593" href="#t593">593</a></span><span class="t"> <span class="nam">filename</span> <span class="op">=</span> <span class="nam">rel_path</span><span class="op">.</span><span class="nam">stem</span>&nbsp;</span><span class="r"></span></p>
676
- <p class="pln"><span class="n"><a id="t594" href="#t594">594</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
677
- <p class="pln"><span class="n"><a id="t595" href="#t595">595</a></span><span class="t"> <span class="com"># Get parent directories between category and file</span>&nbsp;</span><span class="r"></span></p>
678
- <p class="run"><span class="n"><a id="t596" href="#t596">596</a></span><span class="t"> <span class="nam">parent_dirs</span> <span class="op">=</span> <span class="nam">list</span><span class="op">(</span><span class="nam">rel_path</span><span class="op">.</span><span class="nam">parts</span><span class="op">[</span><span class="nam">category_idx</span> <span class="op">+</span> <span class="num">1</span> <span class="op">:</span> <span class="op">-</span><span class="num">1</span><span class="op">]</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
679
- <p class="pln"><span class="n"><a id="t597" href="#t597">597</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
680
- <p class="pln"><span class="n"><a id="t598" href="#t598">598</a></span><span class="t"> <span class="com"># Reverse parent dirs according to spec</span>&nbsp;</span><span class="r"></span></p>
681
- <p class="run"><span class="n"><a id="t599" href="#t599">599</a></span><span class="t"> <span class="nam">parent_dirs</span><span class="op">.</span><span class="nam">reverse</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
682
- <p class="pln"><span class="n"><a id="t600" href="#t600">600</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
683
- <p class="pln"><span class="n"><a id="t601" href="#t601">601</a></span><span class="t"> <span class="com"># Form the ID according to spec</span>&nbsp;</span><span class="r"></span></p>
684
- <p class="run"><span class="n"><a id="t602" href="#t602">602</a></span><span class="t"> <span class="key">if</span> <span class="nam">parent_dirs</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
685
- <p class="run"><span class="n"><a id="t603" href="#t603">603</a></span><span class="t"> <span class="key">return</span> <span class="str">f"{filename}_{'_'.join(parent_dirs)}"</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"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
687
- <p class="run"><span class="n"><a id="t605" href="#t605">605</a></span><span class="t"> <span class="key">return</span> <span class="nam">filename</span>&nbsp;</span><span class="r"></span></p>
688
- <p class="pln"><span class="n"><a id="t606" href="#t606">606</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
689
- <p class="run"><span class="n"><a id="t607" href="#t607">607</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_pydantic_schema_from_ast</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">class_node</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">ClassDef</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</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="str">"""Extract a JSON schema from an AST class definition.</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">&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"> This is a simplified version that extracts basic field information.</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"> For complex annotations, a more sophisticated approach would be needed.</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="str"> """</span>&nbsp;</span><span class="r"></span></p>
695
- <p class="run"><span class="n"><a id="t613" href="#t613">613</a></span><span class="t"> <span class="nam">schema</span> <span class="op">=</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">,</span> <span class="str">"properties"</span><span class="op">:</span> <span class="op">{</span><span class="op">}</span><span class="op">,</span> <span class="str">"required"</span><span class="op">:</span> <span class="op">[</span><span class="op">]</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
696
- <p class="pln"><span class="n"><a id="t614" href="#t614">614</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
697
- <p class="run"><span class="n"><a id="t615" href="#t615">615</a></span><span class="t"> <span class="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">class_node</span><span class="op">.</span><span class="nam">body</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
698
- <p class="run"><span class="n"><a id="t616" href="#t616">616</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">AnnAssign</span><span class="op">)</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">target</span><span class="op">,</span> <span class="nam">ast</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>
699
- <p class="run"><span class="n"><a id="t617" href="#t617">617</a></span><span class="t"> <span class="nam">field_name</span> <span class="op">=</span> <span class="nam">node</span><span class="op">.</span><span class="nam">target</span><span class="op">.</span><span class="nam">id</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">&nbsp;</span><span class="r"></span></p>
701
- <p class="pln"><span class="n"><a id="t619" href="#t619">619</a></span><span class="t"> <span class="com"># Extract type annotation as string</span>&nbsp;</span><span class="r"></span></p>
702
- <p class="run"><span class="n"><a id="t620" href="#t620">620</a></span><span class="t"> <span class="nam">annotation</span> <span class="op">=</span> <span class="str">""</span>&nbsp;</span><span class="r"></span></p>
703
- <p class="run"><span class="n"><a id="t621" href="#t621">621</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">,</span> <span class="nam">ast</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>
704
- <p class="run"><span class="n"><a id="t622" href="#t622">622</a></span><span class="t"> <span class="nam">annotation</span> <span class="op">=</span> <span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">.</span><span class="nam">id</span>&nbsp;</span><span class="r"></span></p>
705
- <p class="mis show_mis"><span class="n"><a id="t623" href="#t623">623</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</span><span class="op">)</span><span class="op">:</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="com"># Simple handling of things like List[str]</span>&nbsp;</span><span class="r"></span></p>
707
- <p class="mis show_mis"><span class="n"><a id="t625" href="#t625">625</a></span><span class="t"> <span class="nam">annotation</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">unparse</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">)</span>&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="key">else</span><span class="op">:</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="nam">annotation</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">unparse</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
710
- <p class="pln"><span class="n"><a id="t628" href="#t628">628</a></span><span class="t">&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"> <span class="com"># Create property definition using improved type extraction</span>&nbsp;</span><span class="r"></span></p>
712
- <p class="run"><span class="n"><a id="t630" href="#t630">630</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</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"> <span class="com"># Use the improved complex type extraction</span>&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="nam">type_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_complex_type_schema</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</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">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">type_schema</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">and</span> <span class="str">"type"</span> <span class="key">in</span> <span class="nam">type_schema</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
716
- <p class="mis show_mis"><span class="n"><a id="t634" href="#t634">634</a></span><span class="t"> <span class="nam">prop</span> <span class="op">=</span> <span class="nam">type_schema</span><span class="op">.</span><span class="nam">copy</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
717
- <p class="mis show_mis"><span class="n"><a id="t635" href="#t635">635</a></span><span class="t"> <span class="nam">prop</span><span class="op">[</span><span class="str">"title"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">field_name</span><span class="op">.</span><span class="nam">replace</span><span class="op">(</span><span class="str">"_"</span><span class="op">,</span> <span class="str">" "</span><span class="op">)</span><span class="op">.</span><span class="nam">title</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
718
- <p class="pln"><span class="n"><a id="t636" href="#t636">636</a></span><span class="t"> <span class="key">else</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="nam">prop</span> <span class="op">=</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"> <span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">annotation</span><span class="op">)</span><span class="op">,</span>&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="str">"title"</span><span class="op">:</span> <span class="nam">field_name</span><span class="op">.</span><span class="nam">replace</span><span class="op">(</span><span class="str">"_"</span><span class="op">,</span> <span class="str">" "</span><span class="op">)</span><span class="op">.</span><span class="nam">title</span><span class="op">(</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
722
- <p class="pln"><span class="n"><a id="t640" href="#t640">640</a></span><span class="t"> <span class="op">}</span>&nbsp;</span><span class="r"></span></p>
723
- <p class="run"><span class="n"><a id="t641" href="#t641">641</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">,</span> <span class="nam">ast</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>
724
- <p class="run"><span class="n"><a id="t642" href="#t642">642</a></span><span class="t"> <span class="nam">prop</span> <span class="op">=</span> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
725
- <p class="pln"><span class="n"><a id="t643" href="#t643">643</a></span><span class="t"> <span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">annotation</span><span class="op">.</span><span class="nam">id</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
726
- <p class="pln"><span class="n"><a id="t644" href="#t644">644</a></span><span class="t"> <span class="str">"title"</span><span class="op">:</span> <span class="nam">field_name</span><span class="op">.</span><span class="nam">replace</span><span class="op">(</span><span class="str">"_"</span><span class="op">,</span> <span class="str">" "</span><span class="op">)</span><span class="op">.</span><span class="nam">title</span><span class="op">(</span><span class="op">)</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="op">}</span>&nbsp;</span><span class="r"></span></p>
728
- <p class="pln"><span class="n"><a id="t646" href="#t646">646</a></span><span class="t"> <span class="key">else</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">prop</span> <span class="op">=</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"> <span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">annotation</span><span class="op">)</span><span class="op">,</span>&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="str">"title"</span><span class="op">:</span> <span class="nam">field_name</span><span class="op">.</span><span class="nam">replace</span><span class="op">(</span><span class="str">"_"</span><span class="op">,</span> <span class="str">" "</span><span class="op">)</span><span class="op">.</span><span class="nam">title</span><span class="op">(</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
732
- <p class="pln"><span class="n"><a id="t650" href="#t650">650</a></span><span class="t"> <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">&nbsp;</span><span class="r"></span></p>
734
- <p class="pln"><span class="n"><a id="t652" href="#t652">652</a></span><span class="t"> <span class="com"># Extract default value if present</span>&nbsp;</span><span class="r"></span></p>
735
- <p class="run"><span class="n"><a id="t653" href="#t653">653</a></span><span class="t"> <span class="key">if</span> <span class="nam">node</span><span class="op">.</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>
736
- <p class="run"><span class="n"><a id="t654" href="#t654">654</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
737
- <p class="pln"><span class="n"><a id="t655" href="#t655">655</a></span><span class="t"> <span class="com"># Simple constant default</span>&nbsp;</span><span class="r"></span></p>
738
- <p class="mis show_mis"><span class="n"><a id="t656" href="#t656">656</a></span><span class="t"> <span class="nam">prop</span><span class="op">[</span><span class="str">"default"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
739
- <p class="run"><span class="n"><a id="t657" href="#t657">657</a></span><span class="t"> <span class="key">elif</span> <span class="op">(</span>&nbsp;</span><span class="r"></span></p>
740
- <p class="pln"><span class="n"><a id="t658" href="#t658">658</a></span><span class="t"> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Call</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
741
- <p class="pln"><span class="n"><a id="t659" href="#t659">659</a></span><span class="t"> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">func</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
742
- <p class="pln"><span class="n"><a id="t660" href="#t660">660</a></span><span class="t"> <span class="key">and</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">func</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"Field"</span>&nbsp;</span><span class="r"></span></p>
743
- <p class="pln"><span class="n"><a id="t661" href="#t661">661</a></span><span class="t"> <span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
744
- <p class="pln"><span class="n"><a id="t662" href="#t662">662</a></span><span class="t"> <span class="com"># Field object - extract its parameters</span>&nbsp;</span><span class="r"></span></p>
745
- <p class="run"><span class="n"><a id="t663" href="#t663">663</a></span><span class="t"> <span class="key">for</span> <span class="nam">keyword</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">keywords</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
746
- <p class="run"><span class="n"><a id="t664" href="#t664">664</a></span><span class="t"> <span class="key">if</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">arg</span> <span class="op">==</span> <span class="str">"default"</span> <span class="key">or</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">arg</span> <span class="op">==</span> <span class="str">"default_factory"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
747
- <p class="mis show_mis"><span class="n"><a id="t665" href="#t665">665</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">keyword</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</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">prop</span><span class="op">[</span><span class="str">"default"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
749
- <p class="run"><span class="n"><a id="t667" href="#t667">667</a></span><span class="t"> <span class="key">elif</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">arg</span> <span class="op">==</span> <span class="str">"description"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
750
- <p class="run"><span class="n"><a id="t668" href="#t668">668</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">keyword</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
751
- <p class="run"><span class="n"><a id="t669" href="#t669">669</a></span><span class="t"> <span class="nam">prop</span><span class="op">[</span><span class="str">"description"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">value</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">elif</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">arg</span> <span class="op">==</span> <span class="str">"title"</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="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">keyword</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</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="nam">prop</span><span class="op">[</span><span class="str">"title"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
755
- <p class="pln"><span class="n"><a id="t673" href="#t673">673</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
756
- <p class="pln"><span class="n"><a id="t674" href="#t674">674</a></span><span class="t"> <span class="com"># Check for position default argument</span>&nbsp;</span><span class="r"></span></p>
757
- <p class="pln"><span class="n"><a id="t675" href="#t675">675</a></span><span class="t"> <span class="com"># (Field(..., "description"))</span>&nbsp;</span><span class="r"></span></p>
758
- <p class="run"><span class="n"><a id="t676" href="#t676">676</a></span><span class="t"> <span class="key">if</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">args</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
759
- <p class="mis show_mis"><span class="n"><a id="t677" href="#t677">677</a></span><span class="t"> <span class="key">for</span> <span class="nam">i</span><span class="op">,</span> <span class="nam">arg</span> <span class="key">in</span> <span class="nam">enumerate</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</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>
760
- <p class="mis show_mis"><span class="n"><a id="t678" href="#t678">678</a></span><span class="t"> <span class="key">if</span> <span class="nam">i</span> <span class="op">==</span> <span class="num">0</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">arg</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</span> <span class="key">and</span> <span class="nam">arg</span><span class="op">.</span><span class="nam">value</span> <span class="op">!=</span> <span class="nam">Ellipsis</span><span class="op">:</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">prop</span><span class="op">[</span><span class="str">"default"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">arg</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
762
- <p class="mis show_mis"><span class="n"><a id="t680" href="#t680">680</a></span><span class="t"> <span class="key">elif</span> <span class="nam">i</span> <span class="op">==</span> <span class="num">1</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">arg</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</span><span class="op">:</span>&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="nam">prop</span><span class="op">[</span><span class="str">"description"</span><span class="op">]</span> <span class="op">=</span> <span class="nam">arg</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
764
- <p class="pln"><span class="n"><a id="t682" href="#t682">682</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
765
- <p class="pln"><span class="n"><a id="t683" href="#t683">683</a></span><span class="t"> <span class="com"># Add to properties</span>&nbsp;</span><span class="r"></span></p>
766
- <p class="run"><span class="n"><a id="t684" href="#t684">684</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"properties"</span><span class="op">]</span><span class="op">[</span><span class="nam">field_name</span><span class="op">]</span> <span class="op">=</span> <span class="nam">prop</span>&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">&nbsp;</span><span class="r"></span></p>
768
- <p class="pln"><span class="n"><a id="t686" href="#t686">686</a></span><span class="t"> <span class="com"># Check if required (no default value or Field(...))</span>&nbsp;</span><span class="r"></span></p>
769
- <p class="run"><span class="n"><a id="t687" href="#t687">687</a></span><span class="t"> <span class="nam">is_required</span> <span class="op">=</span> <span class="key">True</span>&nbsp;</span><span class="r"></span></p>
770
- <p class="run"><span class="n"><a id="t688" href="#t688">688</a></span><span class="t"> <span class="key">if</span> <span class="nam">node</span><span class="op">.</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>
771
- <p class="run"><span class="n"><a id="t689" href="#t689">689</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</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="nam">is_required</span> <span class="op">=</span> <span class="key">False</span>&nbsp;</span><span class="r"></span></p>
773
- <p class="run"><span class="n"><a id="t691" href="#t691">691</a></span><span class="t"> <span class="key">elif</span> <span class="op">(</span>&nbsp;</span><span class="r"></span></p>
774
- <p class="pln"><span class="n"><a id="t692" href="#t692">692</a></span><span class="t"> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Call</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
775
- <p class="pln"><span class="n"><a id="t693" href="#t693">693</a></span><span class="t"> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">func</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
776
- <p class="pln"><span class="n"><a id="t694" href="#t694">694</a></span><span class="t"> <span class="key">and</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">func</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"Field"</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"> <span class="op">)</span><span class="op">:</span>&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"># Field has default if it doesn't use ... or if it has a</span>&nbsp;</span><span class="r"></span></p>
779
- <p class="pln"><span class="n"><a id="t697" href="#t697">697</a></span><span class="t"> <span class="com"># default keyword</span>&nbsp;</span><span class="r"></span></p>
780
- <p class="run"><span class="n"><a id="t698" href="#t698">698</a></span><span class="t"> <span class="nam">has_ellipsis</span> <span class="op">=</span> <span class="key">False</span>&nbsp;</span><span class="r"></span></p>
781
- <p class="run"><span class="n"><a id="t699" href="#t699">699</a></span><span class="t"> <span class="nam">has_default</span> <span class="op">=</span> <span class="key">False</span>&nbsp;</span><span class="r"></span></p>
782
- <p class="pln"><span class="n"><a id="t700" href="#t700">700</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
783
- <p class="run"><span class="n"><a id="t701" href="#t701">701</a></span><span class="t"> <span class="key">if</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">args</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">.</span><span class="nam">value</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">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</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">has_ellipsis</span> <span class="op">=</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</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">value</span> <span class="key">is</span> <span class="nam">Ellipsis</span>&nbsp;</span><span class="r"></span></p>
785
- <p class="pln"><span class="n"><a id="t703" href="#t703">703</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
786
- <p class="run"><span class="n"><a id="t704" href="#t704">704</a></span><span class="t"> <span class="key">for</span> <span class="nam">keyword</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">keywords</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
787
- <p class="run"><span class="n"><a id="t705" href="#t705">705</a></span><span class="t"> <span class="key">if</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">arg</span> <span class="op">==</span> <span class="str">"default"</span> <span class="key">or</span> <span class="nam">keyword</span><span class="op">.</span><span class="nam">arg</span> <span class="op">==</span> <span class="str">"default_factory"</span><span class="op">:</span>&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="nam">has_default</span> <span class="op">=</span> <span class="key">True</span>&nbsp;</span><span class="r"></span></p>
789
- <p class="pln"><span class="n"><a id="t707" href="#t707">707</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
790
- <p class="run"><span class="n"><a id="t708" href="#t708">708</a></span><span class="t"> <span class="nam">is_required</span> <span class="op">=</span> <span class="nam">has_ellipsis</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">has_default</span>&nbsp;</span><span class="r"></span></p>
791
- <p class="pln"><span class="n"><a id="t709" href="#t709">709</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
792
- <p class="run"><span class="n"><a id="t710" href="#t710">710</a></span><span class="t"> <span class="key">if</span> <span class="nam">is_required</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
793
- <p class="run"><span class="n"><a id="t711" href="#t711">711</a></span><span class="t"> <span class="nam">schema</span><span class="op">[</span><span class="str">"required"</span><span class="op">]</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">field_name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
794
- <p class="pln"><span class="n"><a id="t712" href="#t712">712</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
795
- <p class="run"><span class="n"><a id="t713" href="#t713">713</a></span><span class="t"> <span class="key">return</span> <span class="nam">schema</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">&nbsp;</span><span class="r"></span></p>
797
- <p class="run"><span class="n"><a id="t715" href="#t715">715</a></span><span class="t"> <span class="key">def</span> <span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">type_hint</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">str</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">"""Convert a Python type hint to a JSON schema type.</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">&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="str"> This handles complex types and edge cases better than the original version.</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"><span class="str"> """</span>&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"># Handle None type</span>&nbsp;</span><span class="r"></span></p>
803
- <p class="run"><span class="n"><a id="t721" href="#t721">721</a></span><span class="t"> <span class="key">if</span> <span class="nam">type_hint</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">[</span><span class="str">"none"</span><span class="op">,</span> <span class="str">"nonetype"</span><span class="op">]</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">return</span> <span class="str">"null"</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="pln"><span class="n"><a id="t724" href="#t724">724</a></span><span class="t"> <span class="com"># Handle basic types first</span>&nbsp;</span><span class="r"></span></p>
807
- <p class="run"><span class="n"><a id="t725" href="#t725">725</a></span><span class="t"> <span class="nam">type_map</span> <span class="op">=</span> <span class="op">{</span>&nbsp;</span><span class="r"></span></p>
808
- <p class="pln"><span class="n"><a id="t726" href="#t726">726</a></span><span class="t"> <span class="str">"str"</span><span class="op">:</span> <span class="str">"string"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
809
- <p class="pln"><span class="n"><a id="t727" href="#t727">727</a></span><span class="t"> <span class="str">"int"</span><span class="op">:</span> <span class="str">"integer"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
810
- <p class="pln"><span class="n"><a id="t728" href="#t728">728</a></span><span class="t"> <span class="str">"float"</span><span class="op">:</span> <span class="str">"number"</span><span class="op">,</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"> <span class="str">"bool"</span><span class="op">:</span> <span class="str">"boolean"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
812
- <p class="pln"><span class="n"><a id="t730" href="#t730">730</a></span><span class="t"> <span class="str">"list"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">,</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"> <span class="str">"dict"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
814
- <p class="pln"><span class="n"><a id="t732" href="#t732">732</a></span><span class="t"> <span class="str">"any"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">,</span> <span class="com"># Any maps to object</span>&nbsp;</span><span class="r"></span></p>
815
- <p class="pln"><span class="n"><a id="t733" href="#t733">733</a></span><span class="t"> <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">&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="com"># Exact matches for simple types</span>&nbsp;</span><span class="r"></span></p>
818
- <p class="run"><span class="n"><a id="t736" href="#t736">736</a></span><span class="t"> <span class="nam">lower_hint</span> <span class="op">=</span> <span class="nam">type_hint</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>
819
- <p class="run"><span class="n"><a id="t737" href="#t737">737</a></span><span class="t"> <span class="key">if</span> <span class="nam">lower_hint</span> <span class="key">in</span> <span class="nam">type_map</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
820
- <p class="run"><span class="n"><a id="t738" href="#t738">738</a></span><span class="t"> <span class="key">return</span> <span class="nam">type_map</span><span class="op">[</span><span class="nam">lower_hint</span><span class="op">]</span>&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">&nbsp;</span><span class="r"></span></p>
822
- <p class="pln"><span class="n"><a id="t740" href="#t740">740</a></span><span class="t"> <span class="com"># Handle common complex patterns</span>&nbsp;</span><span class="r"></span></p>
823
- <p class="mis show_mis"><span class="n"><a id="t741" href="#t741">741</a></span><span class="t"> <span class="key">if</span> <span class="str">"list["</span> <span class="key">in</span> <span class="nam">type_hint</span> <span class="key">or</span> <span class="str">"List["</span> <span class="key">in</span> <span class="nam">type_hint</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
824
- <p class="mis show_mis"><span class="n"><a id="t742" href="#t742">742</a></span><span class="t"> <span class="key">return</span> <span class="str">"array"</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="key">elif</span> <span class="str">"dict["</span> <span class="key">in</span> <span class="nam">type_hint</span> <span class="key">or</span> <span class="str">"Dict["</span> <span class="key">in</span> <span class="nam">type_hint</span><span class="op">:</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">return</span> <span class="str">"object"</span>&nbsp;</span><span class="r"></span></p>
827
- <p class="mis show_mis"><span class="n"><a id="t745" href="#t745">745</a></span><span class="t"> <span class="key">elif</span> <span class="str">"union["</span> <span class="key">in</span> <span class="nam">type_hint</span> <span class="key">or</span> <span class="str">"Union["</span> <span class="key">in</span> <span class="nam">type_hint</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
828
- <p class="pln"><span class="n"><a id="t746" href="#t746">746</a></span><span class="t"> <span class="com"># For Union types, try to extract the first non-None type</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="key">if</span> <span class="str">"none"</span> <span class="key">in</span> <span class="nam">lower_hint</span> <span class="key">or</span> <span class="str">"nonetype"</span> <span class="key">in</span> <span class="nam">lower_hint</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"> <span class="com"># This is Optional[SomeType] - extract the SomeType</span>&nbsp;</span><span class="r"></span></p>
831
- <p class="mis show_mis"><span class="n"><a id="t749" href="#t749">749</a></span><span class="t"> <span class="key">for</span> <span class="nam">basic_type</span> <span class="key">in</span> <span class="nam">type_map</span><span class="op">:</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">basic_type</span> <span class="key">in</span> <span class="nam">lower_hint</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">return</span> <span class="nam">type_map</span><span class="op">[</span><span class="nam">basic_type</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="key">return</span> <span class="str">"object"</span> <span class="com"># Fallback for complex unions</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">elif</span> <span class="str">"optional["</span> <span class="key">in</span> <span class="nam">type_hint</span> <span class="key">or</span> <span class="str">"Optional["</span> <span class="key">in</span> <span class="nam">type_hint</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
836
- <p class="pln"><span class="n"><a id="t754" href="#t754">754</a></span><span class="t"> <span class="com"># Extract the wrapped type from Optional[Type]</span>&nbsp;</span><span class="r"></span></p>
837
- <p class="mis show_mis"><span class="n"><a id="t755" href="#t755">755</a></span><span class="t"> <span class="key">for</span> <span class="nam">basic_type</span> <span class="key">in</span> <span class="nam">type_map</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
838
- <p class="mis show_mis"><span class="n"><a id="t756" href="#t756">756</a></span><span class="t"> <span class="key">if</span> <span class="nam">basic_type</span> <span class="key">in</span> <span class="nam">lower_hint</span><span class="op">:</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="key">return</span> <span class="nam">type_map</span><span class="op">[</span><span class="nam">basic_type</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
840
- <p class="mis show_mis"><span class="n"><a id="t758" href="#t758">758</a></span><span class="t"> <span class="key">return</span> <span class="str">"object"</span>&nbsp;</span><span class="r"></span></p>
841
- <p class="pln"><span class="n"><a id="t759" href="#t759">759</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
842
- <p class="pln"><span class="n"><a id="t760" href="#t760">760</a></span><span class="t"> <span class="com"># Handle some common pydantic/typing types</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="key">if</span> <span class="nam">any</span><span class="op">(</span><span class="nam">keyword</span> <span class="key">in</span> <span class="nam">lower_hint</span> <span class="key">for</span> <span class="nam">keyword</span> <span class="key">in</span> <span class="op">[</span><span class="str">"basemodel"</span><span class="op">,</span> <span class="str">"model"</span><span class="op">]</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
844
- <p class="mis show_mis"><span class="n"><a id="t762" href="#t762">762</a></span><span class="t"> <span class="key">return</span> <span class="str">"object"</span>&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">&nbsp;</span><span class="r"></span></p>
846
- <p class="pln"><span class="n"><a id="t764" href="#t764">764</a></span><span class="t"> <span class="com"># Check for numeric patterns</span>&nbsp;</span><span class="r"></span></p>
847
- <p class="mis show_mis"><span class="n"><a id="t765" href="#t765">765</a></span><span class="t"> <span class="key">if</span> <span class="nam">any</span><span class="op">(</span><span class="nam">num_type</span> <span class="key">in</span> <span class="nam">lower_hint</span> <span class="key">for</span> <span class="nam">num_type</span> <span class="key">in</span> <span class="op">[</span><span class="str">"int"</span><span class="op">,</span> <span class="str">"integer"</span><span class="op">,</span> <span class="str">"number"</span><span class="op">]</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
848
- <p class="mis show_mis"><span class="n"><a id="t766" href="#t766">766</a></span><span class="t"> <span class="key">return</span> <span class="str">"integer"</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">elif</span> <span class="nam">any</span><span class="op">(</span><span class="nam">num_type</span> <span class="key">in</span> <span class="nam">lower_hint</span> <span class="key">for</span> <span class="nam">num_type</span> <span class="key">in</span> <span class="op">[</span><span class="str">"float"</span><span class="op">,</span> <span class="str">"double"</span><span class="op">,</span> <span class="str">"decimal"</span><span class="op">]</span><span class="op">)</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">return</span> <span class="str">"number"</span>&nbsp;</span><span class="r"></span></p>
851
- <p class="mis show_mis"><span class="n"><a id="t769" href="#t769">769</a></span><span class="t"> <span class="key">elif</span> <span class="nam">any</span><span class="op">(</span><span class="nam">str_type</span> <span class="key">in</span> <span class="nam">lower_hint</span> <span class="key">for</span> <span class="nam">str_type</span> <span class="key">in</span> <span class="op">[</span><span class="str">"str"</span><span class="op">,</span> <span class="str">"string"</span><span class="op">,</span> <span class="str">"text"</span><span class="op">]</span><span class="op">)</span><span class="op">:</span>&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="key">return</span> <span class="str">"string"</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="key">elif</span> <span class="nam">any</span><span class="op">(</span><span class="nam">bool_type</span> <span class="key">in</span> <span class="nam">lower_hint</span> <span class="key">for</span> <span class="nam">bool_type</span> <span class="key">in</span> <span class="op">[</span><span class="str">"bool"</span><span class="op">,</span> <span class="str">"boolean"</span><span class="op">]</span><span class="op">)</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="key">return</span> <span class="str">"boolean"</span>&nbsp;</span><span class="r"></span></p>
855
- <p class="pln"><span class="n"><a id="t773" href="#t773">773</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
856
- <p class="pln"><span class="n"><a id="t774" href="#t774">774</a></span><span class="t"> <span class="com"># Default to object for unknown complex types, string for simple unknowns</span>&nbsp;</span><span class="r"></span></p>
857
- <p class="mis show_mis"><span class="n"><a id="t775" href="#t775">775</a></span><span class="t"> <span class="key">if</span> <span class="str">"["</span> <span class="key">in</span> <span class="nam">type_hint</span> <span class="key">or</span> <span class="str">"."</span> <span class="key">in</span> <span class="nam">type_hint</span><span class="op">:</span>&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="str">"object"</span>&nbsp;</span><span class="r"></span></p>
859
- <p class="pln"><span class="n"><a id="t777" href="#t777">777</a></span><span class="t"> <span class="key">else</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="key">return</span> <span class="str">"string"</span>&nbsp;</span><span class="r"></span></p>
861
- <p class="pln"><span class="n"><a id="t779" href="#t779">779</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
862
- <p class="run"><span class="n"><a id="t780" href="#t780">780</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_dict_from_ast</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">dict_node</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Dict</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</span><span class="op">:</span>&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="str">"""Extract a dictionary from an AST Dict node.</span>&nbsp;</span><span class="r"></span></p>
864
- <p class="pln"><span class="n"><a id="t782" href="#t782">782</a></span><span class="t">&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"> This handles simple literal dictionaries with string keys and</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="str"> boolean/string/number values.</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"> """</span>&nbsp;</span><span class="r"></span></p>
868
- <p class="run"><span class="n"><a id="t786" href="#t786">786</a></span><span class="t"> <span class="nam">result</span> <span class="op">=</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">&nbsp;</span><span class="r"></span></p>
870
- <p class="run"><span class="n"><a id="t788" href="#t788">788</a></span><span class="t"> <span class="key">for</span> <span class="nam">key</span><span class="op">,</span> <span class="nam">value</span> <span class="key">in</span> <span class="nam">zip</span><span class="op">(</span><span class="nam">dict_node</span><span class="op">.</span><span class="nam">keys</span><span class="op">,</span> <span class="nam">dict_node</span><span class="op">.</span><span class="nam">values</span><span class="op">,</span> <span class="nam">strict</span><span class="op">=</span><span class="key">False</span><span class="op">)</span><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"> <span class="com"># Extract the key</span>&nbsp;</span><span class="r"></span></p>
872
- <p class="run"><span class="n"><a id="t790" href="#t790">790</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">key</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</span> <span class="key">and</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">key</span><span class="op">.</span><span class="nam">value</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>
873
- <p class="run"><span class="n"><a id="t791" href="#t791">791</a></span><span class="t"> <span class="nam">key_str</span> <span class="op">=</span> <span class="nam">key</span><span class="op">.</span><span class="nam">value</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">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">key</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Str</span><span class="op">)</span><span class="op">:</span> <span class="com"># For older Python versions</span>&nbsp;</span><span class="r"></span></p>
875
- <p class="mis show_mis"><span class="n"><a id="t793" href="#t793">793</a></span><span class="t"> <span class="nam">key_str</span> <span class="op">=</span> <span class="nam">key</span><span class="op">.</span><span class="nam">s</span>&nbsp;</span><span class="r"></span></p>
876
- <p class="pln"><span class="n"><a id="t794" href="#t794">794</a></span><span class="t"> <span class="key">else</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
877
- <p class="pln"><span class="n"><a id="t795" href="#t795">795</a></span><span class="t"> <span class="com"># Skip non-string keys</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="key">continue</span>&nbsp;</span><span class="r"></span></p>
879
- <p class="pln"><span class="n"><a id="t797" href="#t797">797</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
880
- <p class="pln"><span class="n"><a id="t798" href="#t798">798</a></span><span class="t"> <span class="com"># Extract the value</span>&nbsp;</span><span class="r"></span></p>
881
- <p class="run"><span class="n"><a id="t799" href="#t799">799</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Constant</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
882
- <p class="pln"><span class="n"><a id="t800" href="#t800">800</a></span><span class="t"> <span class="com"># Handles strings, numbers, booleans, None</span>&nbsp;</span><span class="r"></span></p>
883
- <p class="run"><span class="n"><a id="t801" href="#t801">801</a></span><span class="t"> <span class="nam">result</span><span class="op">[</span><span class="nam">key_str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">value</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
884
- <p class="run"><span class="n"><a id="t802" href="#t802">802</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Str</span><span class="op">)</span><span class="op">:</span> <span class="com"># For older Python versions</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="nam">result</span><span class="op">[</span><span class="nam">key_str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">value</span><span class="op">.</span><span class="nam">s</span>&nbsp;</span><span class="r"></span></p>
886
- <p class="run"><span class="n"><a id="t804" href="#t804">804</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Num</span><span class="op">)</span><span class="op">:</span> <span class="com"># For older Python versions</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="nam">result</span><span class="op">[</span><span class="nam">key_str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">value</span><span class="op">.</span><span class="nam">n</span>&nbsp;</span><span class="r"></span></p>
888
- <p class="run"><span class="n"><a id="t806" href="#t806">806</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">NameConstant</span><span class="op">)</span><span class="op">:</span> <span class="com"># For older Python versions (True/False/None)</span>&nbsp;</span><span class="r"></span></p>
889
- <p class="mis show_mis"><span class="n"><a id="t807" href="#t807">807</a></span><span class="t"> <span class="nam">result</span><span class="op">[</span><span class="nam">key_str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">value</span><span class="op">.</span><span class="nam">value</span>&nbsp;</span><span class="r"></span></p>
890
- <p class="run"><span class="n"><a id="t808" href="#t808">808</a></span><span class="t"> <span class="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</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>
891
- <p class="pln"><span class="n"><a id="t809" href="#t809">809</a></span><span class="t"> <span class="com"># Handle True/False/None as names</span>&nbsp;</span><span class="r"></span></p>
892
- <p class="run"><span class="n"><a id="t810" href="#t810">810</a></span><span class="t"> <span class="key">if</span> <span class="nam">value</span><span class="op">.</span><span class="nam">id</span> <span class="key">in</span> <span class="op">(</span><span class="str">"True"</span><span class="op">,</span> <span class="str">"False"</span><span class="op">,</span> <span class="str">"None"</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
893
- <p class="mis show_mis"><span class="n"><a id="t811" href="#t811">811</a></span><span class="t"> <span class="nam">result</span><span class="op">[</span><span class="nam">key_str</span><span class="op">]</span> <span class="op">=</span> <span class="op">{</span><span class="str">"True"</span><span class="op">:</span> <span class="key">True</span><span class="op">,</span> <span class="str">"False"</span><span class="op">:</span> <span class="key">False</span><span class="op">,</span> <span class="str">"None"</span><span class="op">:</span> <span class="key">None</span><span class="op">}</span><span class="op">[</span><span class="nam">value</span><span class="op">.</span><span class="nam">id</span><span class="op">]</span>&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"># We could add more complex value handling here if needed</span>&nbsp;</span><span class="r"></span></p>
895
- <p class="pln"><span class="n"><a id="t813" href="#t813">813</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
896
- <p class="run"><span class="n"><a id="t814" href="#t814">814</a></span><span class="t"> <span class="key">return</span> <span class="nam">result</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="run"><span class="n"><a id="t816" href="#t816">816</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_complex_type_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">subscript</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</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"> <span class="str">"""Extract schema from complex types like list[str], dict[str, Any], etc."""</span>&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="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">value</span><span class="op">,</span> <span class="nam">ast</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>
901
- <p class="mis show_mis"><span class="n"><a id="t819" href="#t819">819</a></span><span class="t"> <span class="nam">base_type</span> <span class="op">=</span> <span class="nam">subscript</span><span class="op">.</span><span class="nam">value</span><span class="op">.</span><span class="nam">id</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">&nbsp;</span><span class="r"></span></p>
903
- <p class="mis show_mis"><span class="n"><a id="t821" href="#t821">821</a></span><span class="t"> <span class="key">if</span> <span class="nam">base_type</span> <span class="op">==</span> <span class="str">"list"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
904
- <p class="pln"><span class="n"><a id="t822" href="#t822">822</a></span><span class="t"> <span class="com"># Handle list[ItemType]</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">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">,</span> <span class="nam">ast</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>
906
- <p class="mis show_mis"><span class="n"><a id="t824" href="#t824">824</a></span><span class="t"> <span class="nam">item_type</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">.</span><span class="nam">id</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
907
- <p class="mis show_mis"><span class="n"><a id="t825" href="#t825">825</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">,</span> <span class="str">"items"</span><span class="op">:</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">item_type</span><span class="op">}</span><span class="op">}</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="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</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"> <span class="com"># Nested subscript like list[dict[str, Any]]</span>&nbsp;</span><span class="r"></span></p>
910
- <p class="mis show_mis"><span class="n"><a id="t828" href="#t828">828</a></span><span class="t"> <span class="nam">item_schema</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_complex_type_schema</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">)</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="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">,</span> <span class="str">"items"</span><span class="op">:</span> <span class="nam">item_schema</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
912
- <p class="pln"><span class="n"><a id="t830" href="#t830">830</a></span><span class="t"> <span class="key">else</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"># Complex item type, try to parse it</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">item_type_str</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">unparse</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</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="key">if</span> <span class="str">"dict"</span> <span class="key">in</span> <span class="nam">item_type_str</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
916
- <p class="mis show_mis"><span class="n"><a id="t834" href="#t834">834</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">,</span> <span class="str">"items"</span><span class="op">:</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">}</span><span class="op">}</span>&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="key">else</span><span class="op">:</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">item_type</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">item_type_str</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">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"array"</span><span class="op">,</span> <span class="str">"items"</span><span class="op">:</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">item_type</span><span class="op">}</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
920
- <p class="pln"><span class="n"><a id="t838" href="#t838">838</a></span><span class="t">&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="key">elif</span> <span class="nam">base_type</span> <span class="op">==</span> <span class="str">"dict"</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">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="str">"object"</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
923
- <p class="pln"><span class="n"><a id="t841" href="#t841">841</a></span><span class="t">&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="key">elif</span> <span class="nam">base_type</span> <span class="key">in</span> <span class="op">[</span><span class="str">"Optional"</span><span class="op">,</span> <span class="str">"Union"</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
925
- <p class="pln"><span class="n"><a id="t843" href="#t843">843</a></span><span class="t"> <span class="com"># Handle Optional[Type] or Union[Type, None]</span>&nbsp;</span><span class="r"></span></p>
926
- <p class="mis show_mis"><span class="n"><a id="t844" href="#t844">844</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_handle_optional_type</span><span class="op">(</span><span class="nam">subscript</span><span class="op">)</span>&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">&nbsp;</span><span class="r"></span></p>
928
- <p class="pln"><span class="n"><a id="t846" href="#t846">846</a></span><span class="t"> <span class="com"># Fallback</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="nam">type_str</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">unparse</span><span class="op">(</span><span class="nam">subscript</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="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">type_str</span><span class="op">)</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
931
- <p class="pln"><span class="n"><a id="t849" href="#t849">849</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
932
- <p class="run"><span class="n"><a id="t850" href="#t850">850</a></span><span class="t"> <span class="key">def</span> <span class="nam">_handle_union_type</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">union_node</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">BinOp</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
933
- <p class="pln"><span class="n"><a id="t851" href="#t851">851</a></span><span class="t"> <span class="str">"""Handle union types like str | None."""</span>&nbsp;</span><span class="r"></span></p>
934
- <p class="pln"><span class="n"><a id="t852" href="#t852">852</a></span><span class="t"> <span class="com"># For now, just extract the first non-None type</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">left_type</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_type_from_node</span><span class="op">(</span><span class="nam">union_node</span><span class="op">.</span><span class="nam">left</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
936
- <p class="mis show_mis"><span class="n"><a id="t854" href="#t854">854</a></span><span class="t"> <span class="nam">right_type</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_type_from_node</span><span class="op">(</span><span class="nam">union_node</span><span class="op">.</span><span class="nam">right</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
937
- <p class="pln"><span class="n"><a id="t855" href="#t855">855</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
938
- <p class="pln"><span class="n"><a id="t856" href="#t856">856</a></span><span class="t"> <span class="com"># If one side is None, return the other type</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="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">right_type</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span> <span class="key">and</span> <span class="nam">right_type</span> <span class="op">==</span> <span class="str">"null"</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
940
- <p class="mis show_mis"><span class="n"><a id="t858" href="#t858">858</a></span><span class="t"> <span class="key">return</span> <span class="nam">left_type</span> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">left_type</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">else</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">left_type</span><span class="op">}</span>&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="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">left_type</span><span class="op">,</span> <span class="nam">str</span><span class="op">)</span> <span class="key">and</span> <span class="nam">left_type</span> <span class="op">==</span> <span class="str">"null"</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">return</span> <span class="nam">right_type</span> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">right_type</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">else</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">right_type</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
943
- <p class="pln"><span class="n"><a id="t861" href="#t861">861</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
944
- <p class="pln"><span class="n"><a id="t862" href="#t862">862</a></span><span class="t"> <span class="com"># Otherwise, return the first type</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">return</span> <span class="nam">left_type</span> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">left_type</span><span class="op">,</span> <span class="nam">dict</span><span class="op">)</span> <span class="key">else</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">left_type</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
946
- <p class="pln"><span class="n"><a id="t864" href="#t864">864</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
947
- <p class="run"><span class="n"><a id="t865" href="#t865">865</a></span><span class="t"> <span class="key">def</span> <span class="nam">_handle_optional_type</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">subscript</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</span><span class="op">:</span>&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="str">"""Handle Optional[Type] annotations."""</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="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">,</span> <span class="nam">ast</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>
950
- <p class="mis show_mis"><span class="n"><a id="t868" href="#t868">868</a></span><span class="t"> <span class="nam">base_type</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">.</span><span class="nam">id</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="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">base_type</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">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</span><span class="op">)</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">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_complex_type_schema</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
954
- <p class="pln"><span class="n"><a id="t872" href="#t872">872</a></span><span class="t"> <span class="key">else</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="nam">type_str</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">unparse</span><span class="op">(</span><span class="nam">subscript</span><span class="op">.</span><span class="nam">slice</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="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">type_str</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="run"><span class="n"><a id="t876" href="#t876">876</a></span><span class="t"> <span class="key">def</span> <span class="nam">_is_parameter_required</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">position</span><span class="op">:</span> <span class="nam">int</span><span class="op">,</span> <span class="nam">defaults</span><span class="op">:</span> <span class="nam">list</span><span class="op">,</span> <span class="nam">total_args</span><span class="op">:</span> <span class="nam">int</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>
959
- <p class="pln"><span class="n"><a id="t877" href="#t877">877</a></span><span class="t"> <span class="str">"""Check if a function parameter is required (has no default value)."""</span>&nbsp;</span><span class="r"></span></p>
960
- <p class="mis show_mis"><span class="n"><a id="t878" href="#t878">878</a></span><span class="t"> <span class="key">if</span> <span class="nam">position</span> <span class="op">>=</span> <span class="nam">total_args</span> <span class="key">or</span> <span class="nam">position</span> <span class="op">&lt;</span> <span class="num">0</span><span class="op">:</span>&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">return</span> <span class="key">True</span> <span class="com"># Default to required if position is out of range</span>&nbsp;</span><span class="r"></span></p>
962
- <p class="pln"><span class="n"><a id="t880" href="#t880">880</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
963
- <p class="pln"><span class="n"><a id="t881" href="#t881">881</a></span><span class="t"> <span class="com"># If there are no defaults, all parameters are required</span>&nbsp;</span><span class="r"></span></p>
964
- <p class="mis show_mis"><span class="n"><a id="t882" href="#t882">882</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">defaults</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
965
- <p class="mis show_mis"><span class="n"><a id="t883" href="#t883">883</a></span><span class="t"> <span class="key">return</span> <span class="key">True</span>&nbsp;</span><span class="r"></span></p>
966
- <p class="pln"><span class="n"><a id="t884" href="#t884">884</a></span><span class="t">&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"> <span class="com"># Defaults apply to the last N parameters where N = len(defaults)</span>&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"># So if we have 4 args and 2 defaults, defaults apply to args[2] and args[3]</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="nam">args_with_defaults</span> <span class="op">=</span> <span class="nam">len</span><span class="op">(</span><span class="nam">defaults</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">first_default_position</span> <span class="op">=</span> <span class="nam">total_args</span> <span class="op">-</span> <span class="nam">args_with_defaults</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"># If this parameter's position is before the first default position,</span>&nbsp;</span><span class="r"></span></p>
973
- <p class="pln"><span class="n"><a id="t891" href="#t891">891</a></span><span class="t"> <span class="com"># it's required</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">return</span> <span class="nam">position</span> <span class="op">&lt;</span> <span class="nam">first_default_position</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="run"><span class="n"><a id="t894" href="#t894">894</a></span><span class="t"> <span class="key">def</span> <span class="nam">_extract_return_type_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">return_annotation</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">AST</span><span class="op">,</span> <span class="nam">tree</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Module</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
977
- <p class="pln"><span class="n"><a id="t895" href="#t895">895</a></span><span class="t"> <span class="str">"""Extract schema from function return type annotation."""</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="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">return_annotation</span><span class="op">,</span> <span class="nam">ast</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>
979
- <p class="pln"><span class="n"><a id="t897" href="#t897">897</a></span><span class="t"> <span class="com"># Simple type like str, int, or a class name</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="key">if</span> <span class="nam">return_annotation</span><span class="op">.</span><span class="nam">id</span> <span class="key">in</span> <span class="op">[</span><span class="str">"str"</span><span class="op">,</span> <span class="str">"int"</span><span class="op">,</span> <span class="str">"float"</span><span class="op">,</span> <span class="str">"bool"</span><span class="op">,</span> <span class="str">"list"</span><span class="op">,</span> <span class="str">"dict"</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">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">return_annotation</span><span class="op">.</span><span class="nam">id</span><span class="op">)</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
982
- <p class="pln"><span class="n"><a id="t900" href="#t900">900</a></span><span class="t"> <span class="key">else</span><span class="op">:</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"> <span class="com"># Assume it's a Pydantic model class - look for it in the module</span>&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">self</span><span class="op">.</span><span class="nam">_find_class_schema</span><span class="op">(</span><span class="nam">return_annotation</span><span class="op">.</span><span class="nam">id</span><span class="op">,</span> <span class="nam">tree</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
985
- <p class="pln"><span class="n"><a id="t903" href="#t903">903</a></span><span class="t">&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="key">elif</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">return_annotation</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Subscript</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
987
- <p class="pln"><span class="n"><a id="t905" href="#t905">905</a></span><span class="t"> <span class="com"># Complex type like list[dict], Optional[MyClass], etc.</span>&nbsp;</span><span class="r"></span></p>
988
- <p class="mis show_mis"><span class="n"><a id="t906" href="#t906">906</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_complex_type_schema</span><span class="op">(</span><span class="nam">return_annotation</span><span class="op">)</span>&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">&nbsp;</span><span class="r"></span></p>
990
- <p class="pln"><span class="n"><a id="t908" href="#t908">908</a></span><span class="t"> <span class="key">else</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="com"># Other complex types</span>&nbsp;</span><span class="r"></span></p>
992
- <p class="mis show_mis"><span class="n"><a id="t910" href="#t910">910</a></span><span class="t"> <span class="nam">type_str</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">unparse</span><span class="op">(</span><span class="nam">return_annotation</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
993
- <p class="mis show_mis"><span class="n"><a id="t911" href="#t911">911</a></span><span class="t"> <span class="key">return</span> <span class="op">{</span><span class="str">"type"</span><span class="op">:</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_type_hint_to_json_type</span><span class="op">(</span><span class="nam">type_str</span><span class="op">)</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">&nbsp;</span><span class="r"></span></p>
995
- <p class="run"><span class="n"><a id="t913" href="#t913">913</a></span><span class="t"> <span class="key">def</span> <span class="nam">_find_class_schema</span><span class="op">(</span><span class="nam">self</span><span class="op">,</span> <span class="nam">class_name</span><span class="op">:</span> <span class="nam">str</span><span class="op">,</span> <span class="nam">tree</span><span class="op">:</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Module</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
996
- <p class="pln"><span class="n"><a id="t914" href="#t914">914</a></span><span class="t"> <span class="str">"""Find a class definition in the module and extract its schema."""</span>&nbsp;</span><span class="r"></span></p>
997
- <p class="mis show_mis"><span class="n"><a id="t915" href="#t915">915</a></span><span class="t"> <span class="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">tree</span><span class="op">.</span><span class="nam">body</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
998
- <p class="mis show_mis"><span class="n"><a id="t916" href="#t916">916</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">ClassDef</span><span class="op">)</span> <span class="key">and</span> <span class="nam">node</span><span class="op">.</span><span class="nam">name</span> <span class="op">==</span> <span class="nam">class_name</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
999
- <p class="pln"><span class="n"><a id="t917" href="#t917">917</a></span><span class="t"> <span class="com"># Check if it inherits from BaseModel</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">for</span> <span class="nam">base</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">bases</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1001
- <p class="mis show_mis"><span class="n"><a id="t919" href="#t919">919</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">base</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Name</span><span class="op">)</span> <span class="key">and</span> <span class="nam">base</span><span class="op">.</span><span class="nam">id</span> <span class="op">==</span> <span class="str">"BaseModel"</span><span class="op">:</span>&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="key">return</span> <span class="nam">self</span><span class="op">.</span><span class="nam">_extract_pydantic_schema_from_ast</span><span class="op">(</span><span class="nam">node</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1003
- <p class="pln"><span class="n"><a id="t921" href="#t921">921</a></span><span class="t">&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="key">return</span> <span class="key">None</span>&nbsp;</span><span class="r"></span></p>
1005
- <p class="pln"><span class="n"><a id="t923" href="#t923">923</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1006
- <p class="pln"><span class="n"><a id="t924" href="#t924">924</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1007
- <p class="run"><span class="n"><a id="t925" href="#t925">925</a></span><span class="t"><span class="key">def</span> <span class="nam">parse_project</span><span class="op">(</span><span class="nam">project_path</span><span class="op">:</span> <span class="nam">Path</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">ComponentType</span><span class="op">,</span> <span class="nam">list</span><span class="op">[</span><span class="nam">ParsedComponent</span><span class="op">]</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1008
- <p class="pln"><span class="n"><a id="t926" href="#t926">926</a></span><span class="t"> <span class="str">"""Parse a GolfMCP project to extract all components."""</span>&nbsp;</span><span class="r"></span></p>
1009
- <p class="run"><span class="n"><a id="t927" href="#t927">927</a></span><span class="t"> <span class="nam">parser</span> <span class="op">=</span> <span class="nam">AstParser</span><span class="op">(</span><span class="nam">project_path</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1010
- <p class="pln"><span class="n"><a id="t928" href="#t928">928</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1011
- <p class="run"><span class="n"><a id="t929" href="#t929">929</a></span><span class="t"> <span class="nam">components</span><span class="op">:</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">ComponentType</span><span class="op">,</span> <span class="nam">list</span><span class="op">[</span><span class="nam">ParsedComponent</span><span class="op">]</span><span class="op">]</span> <span class="op">=</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="nam">ComponentType</span><span class="op">.</span><span class="nam">TOOL</span><span class="op">:</span> <span class="op">[</span><span class="op">]</span><span class="op">,</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="nam">ComponentType</span><span class="op">.</span><span class="nam">RESOURCE</span><span class="op">:</span> <span class="op">[</span><span class="op">]</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1014
- <p class="pln"><span class="n"><a id="t932" href="#t932">932</a></span><span class="t"> <span class="nam">ComponentType</span><span class="op">.</span><span class="nam">PROMPT</span><span class="op">:</span> <span class="op">[</span><span class="op">]</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1015
- <p class="pln"><span class="n"><a id="t933" href="#t933">933</a></span><span class="t"> <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"># Parse each directory</span>&nbsp;</span><span class="r"></span></p>
1018
- <p class="run"><span class="n"><a id="t936" href="#t936">936</a></span><span class="t"> <span class="key">for</span> <span class="nam">comp_type</span><span class="op">,</span> <span class="nam">dir_name</span> <span class="key">in</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"> <span class="op">(</span><span class="nam">ComponentType</span><span class="op">.</span><span class="nam">TOOL</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>
1020
- <p class="pln"><span class="n"><a id="t938" href="#t938">938</a></span><span class="t"> <span class="op">(</span><span class="nam">ComponentType</span><span class="op">.</span><span class="nam">RESOURCE</span><span class="op">,</span> <span class="str">"resources"</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1021
- <p class="pln"><span class="n"><a id="t939" href="#t939">939</a></span><span class="t"> <span class="op">(</span><span class="nam">ComponentType</span><span class="op">.</span><span class="nam">PROMPT</span><span class="op">,</span> <span class="str">"prompts"</span><span class="op">)</span><span class="op">,</span>&nbsp;</span><span class="r"></span></p>
1022
- <p class="pln"><span class="n"><a id="t940" href="#t940">940</a></span><span class="t"> <span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1023
- <p class="run"><span class="n"><a id="t941" href="#t941">941</a></span><span class="t"> <span class="nam">dir_path</span> <span class="op">=</span> <span class="nam">project_path</span> <span class="op">/</span> <span class="nam">dir_name</span>&nbsp;</span><span class="r"></span></p>
1024
- <p class="run"><span class="n"><a id="t942" href="#t942">942</a></span><span class="t"> <span class="key">if</span> <span class="nam">dir_path</span><span class="op">.</span><span class="nam">exists</span><span class="op">(</span><span class="op">)</span> <span class="key">and</span> <span class="nam">dir_path</span><span class="op">.</span><span class="nam">is_dir</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1025
- <p class="run"><span class="n"><a id="t943" href="#t943">943</a></span><span class="t"> <span class="nam">dir_components</span> <span class="op">=</span> <span class="nam">parser</span><span class="op">.</span><span class="nam">parse_directory</span><span class="op">(</span><span class="nam">dir_path</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1026
- <p class="run"><span class="n"><a id="t944" href="#t944">944</a></span><span class="t"> <span class="nam">components</span><span class="op">[</span><span class="nam">comp_type</span><span class="op">]</span><span class="op">.</span><span class="nam">extend</span><span class="op">(</span><span class="op">[</span><span class="nam">c</span> <span class="key">for</span> <span class="nam">c</span> <span class="key">in</span> <span class="nam">dir_components</span> <span class="key">if</span> <span class="nam">c</span><span class="op">.</span><span class="nam">type</span> <span class="op">==</span> <span class="nam">comp_type</span><span class="op">]</span><span class="op">)</span>&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">&nbsp;</span><span class="r"></span></p>
1028
- <p class="pln"><span class="n"><a id="t946" href="#t946">946</a></span><span class="t"> <span class="com"># Check for ID collisions</span>&nbsp;</span><span class="r"></span></p>
1029
- <p class="run"><span class="n"><a id="t947" href="#t947">947</a></span><span class="t"> <span class="nam">all_ids</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span>&nbsp;</span><span class="r"></span></p>
1030
- <p class="run"><span class="n"><a id="t948" href="#t948">948</a></span><span class="t"> <span class="key">for</span> <span class="nam">comp_type</span><span class="op">,</span> <span class="nam">comps</span> <span class="key">in</span> <span class="nam">components</span><span class="op">.</span><span class="nam">items</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1031
- <p class="run"><span class="n"><a id="t949" href="#t949">949</a></span><span class="t"> <span class="key">for</span> <span class="nam">comp</span> <span class="key">in</span> <span class="nam">comps</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1032
- <p class="run"><span class="n"><a id="t950" href="#t950">950</a></span><span class="t"> <span class="key">if</span> <span class="nam">comp</span><span class="op">.</span><span class="nam">name</span> <span class="key">in</span> <span class="nam">all_ids</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1033
- <p class="run"><span class="n"><a id="t951" href="#t951">951</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"ID collision detected: {comp.name} is used by multiple components"</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1034
- <p class="run"><span class="n"><a id="t952" href="#t952">952</a></span><span class="t"> <span class="nam">all_ids</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">comp</span><span class="op">.</span><span class="nam">name</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1035
- <p class="pln"><span class="n"><a id="t953" href="#t953">953</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1036
- <p class="run"><span class="n"><a id="t954" href="#t954">954</a></span><span class="t"> <span class="key">return</span> <span class="nam">components</span>&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">&nbsp;</span><span class="r"></span></p>
1038
- <p class="pln"><span class="n"><a id="t956" href="#t956">956</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1039
- <p class="run"><span class="n"><a id="t957" href="#t957">957</a></span><span class="t"><span class="key">def</span> <span class="nam">parse_common_files</span><span class="op">(</span><span class="nam">project_path</span><span class="op">:</span> <span class="nam">Path</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
1040
- <p class="pln"><span class="n"><a id="t958" href="#t958">958</a></span><span class="t"> <span class="str">"""Find all common.py files in the project.</span>&nbsp;</span><span class="r"></span></p>
1041
- <p class="pln"><span class="n"><a id="t959" href="#t959">959</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1042
- <p class="pln"><span class="n"><a id="t960" href="#t960">960</a></span><span class="t"><span class="str"> Args:</span>&nbsp;</span><span class="r"></span></p>
1043
- <p class="pln"><span class="n"><a id="t961" href="#t961">961</a></span><span class="t"><span class="str"> project_path: Path to the project root</span>&nbsp;</span><span class="r"></span></p>
1044
- <p class="pln"><span class="n"><a id="t962" href="#t962">962</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1045
- <p class="pln"><span class="n"><a id="t963" href="#t963">963</a></span><span class="t"><span class="str"> Returns:</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"><span class="str"> Dictionary mapping directory paths to common.py file paths</span>&nbsp;</span><span class="r"></span></p>
1047
- <p class="pln"><span class="n"><a id="t965" href="#t965">965</a></span><span class="t"><span class="str"> """</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="nam">common_files</span> <span class="op">=</span> <span class="op">{</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
1049
- <p class="pln"><span class="n"><a id="t967" href="#t967">967</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1050
- <p class="pln"><span class="n"><a id="t968" href="#t968">968</a></span><span class="t"> <span class="com"># Search for common.py files in tools, resources, and prompts directories</span>&nbsp;</span><span class="r"></span></p>
1051
- <p class="mis show_mis"><span class="n"><a id="t969" href="#t969">969</a></span><span class="t"> <span class="key">for</span> <span class="nam">dir_name</span> <span class="key">in</span> <span class="op">[</span><span class="str">"tools"</span><span class="op">,</span> <span class="str">"resources"</span><span class="op">,</span> <span class="str">"prompts"</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1052
- <p class="mis show_mis"><span class="n"><a id="t970" href="#t970">970</a></span><span class="t"> <span class="nam">base_dir</span> <span class="op">=</span> <span class="nam">project_path</span> <span class="op">/</span> <span class="nam">dir_name</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="key">if</span> <span class="key">not</span> <span class="nam">base_dir</span><span class="op">.</span><span class="nam">exists</span><span class="op">(</span><span class="op">)</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">base_dir</span><span class="op">.</span><span class="nam">is_dir</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1054
- <p class="mis show_mis"><span class="n"><a id="t972" href="#t972">972</a></span><span class="t"> <span class="key">continue</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">&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="com"># Find all common.py files (recursively)</span>&nbsp;</span><span class="r"></span></p>
1057
- <p class="mis show_mis"><span class="n"><a id="t975" href="#t975">975</a></span><span class="t"> <span class="key">for</span> <span class="nam">common_file</span> <span class="key">in</span> <span class="nam">base_dir</span><span class="op">.</span><span class="nam">glob</span><span class="op">(</span><span class="str">"**/common.py"</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="com"># Skip files in __pycache__ or other hidden directories</span>&nbsp;</span><span class="r"></span></p>
1059
- <p class="mis show_mis"><span class="n"><a id="t977" href="#t977">977</a></span><span class="t"> <span class="key">if</span> <span class="str">"__pycache__"</span> <span class="key">in</span> <span class="nam">common_file</span><span class="op">.</span><span class="nam">parts</span> <span class="key">or</span> <span class="nam">any</span><span class="op">(</span><span class="nam">part</span><span class="op">.</span><span class="nam">startswith</span><span class="op">(</span><span class="str">"."</span><span class="op">)</span> <span class="key">for</span> <span class="nam">part</span> <span class="key">in</span> <span class="nam">common_file</span><span class="op">.</span><span class="nam">parts</span><span class="op">)</span><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">continue</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="pln"><span class="n"><a id="t980" href="#t980">980</a></span><span class="t"> <span class="com"># Get the parent directory as the module path</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="nam">module_path</span> <span class="op">=</span> <span class="nam">str</span><span class="op">(</span><span class="nam">common_file</span><span class="op">.</span><span class="nam">parent</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">project_path</span><span class="op">)</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1064
- <p class="mis show_mis"><span class="n"><a id="t982" href="#t982">982</a></span><span class="t"> <span class="nam">common_files</span><span class="op">[</span><span class="nam">module_path</span><span class="op">]</span> <span class="op">=</span> <span class="nam">common_file</span>&nbsp;</span><span class="r"></span></p>
1065
- <p class="pln"><span class="n"><a id="t983" href="#t983">983</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1066
- <p class="mis show_mis"><span class="n"><a id="t984" href="#t984">984</a></span><span class="t"> <span class="key">return</span> <span class="nam">common_files</span>&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="pln"><span class="n"><a id="t986" href="#t986">986</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1069
- <p class="run"><span class="n"><a id="t987" href="#t987">987</a></span><span class="t"><span class="key">def</span> <span class="nam">_is_golf_component_file</span><span class="op">(</span><span class="nam">file_path</span><span class="op">:</span> <span class="nam">Path</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>
1070
- <p class="pln"><span class="n"><a id="t988" href="#t988">988</a></span><span class="t"> <span class="str">"""Check if a Python file is a Golf component (has export or resource_uri).</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"><span class="str"> </span>&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="str"> Args:</span>&nbsp;</span><span class="r"></span></p>
1073
- <p class="pln"><span class="n"><a id="t991" href="#t991">991</a></span><span class="t"><span class="str"> file_path: Path to the Python file to check</span>&nbsp;</span><span class="r"></span></p>
1074
- <p class="pln"><span class="n"><a id="t992" href="#t992">992</a></span><span class="t"><span class="str"> </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"><span class="str"> Returns:</span>&nbsp;</span><span class="r"></span></p>
1076
- <p class="pln"><span class="n"><a id="t994" href="#t994">994</a></span><span class="t"><span class="str"> True if the file appears to be a Golf component, False otherwise</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"><span class="str"> """</span>&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="key">try</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">with</span> <span class="nam">open</span><span class="op">(</span><span class="nam">file_path</span><span class="op">,</span> <span class="str">'r'</span><span class="op">,</span> <span class="nam">encoding</span><span class="op">=</span><span class="str">'utf-8'</span><span class="op">)</span> <span class="key">as</span> <span class="nam">f</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1080
- <p class="mis show_mis"><span class="n"><a id="t998" href="#t998">998</a></span><span class="t"> <span class="nam">content</span> <span class="op">=</span> <span class="nam">f</span><span class="op">.</span><span class="nam">read</span><span class="op">(</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1081
- <p class="pln"><span class="n"><a id="t999" href="#t999">999</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1082
- <p class="pln"><span class="n"><a id="t1000" href="#t1000">1000</a></span><span class="t"> <span class="com"># Parse the file to check for Golf component patterns</span>&nbsp;</span><span class="r"></span></p>
1083
- <p class="mis show_mis"><span class="n"><a id="t1001" href="#t1001">1001</a></span><span class="t"> <span class="nam">tree</span> <span class="op">=</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">parse</span><span class="op">(</span><span class="nam">content</span><span class="op">)</span>&nbsp;</span><span class="r"></span></p>
1084
- <p class="pln"><span class="n"><a id="t1002" href="#t1002">1002</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1085
- <p class="pln"><span class="n"><a id="t1003" href="#t1003">1003</a></span><span class="t"> <span class="com"># Look for 'export' or 'resource_uri' variable assignments</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="key">for</span> <span class="nam">node</span> <span class="key">in</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">walk</span><span class="op">(</span><span class="nam">tree</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1087
- <p class="mis show_mis"><span class="n"><a id="t1005" href="#t1005">1005</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">node</span><span class="op">,</span> <span class="nam">ast</span><span class="op">.</span><span class="nam">Assign</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1088
- <p class="mis show_mis"><span class="n"><a id="t1006" href="#t1006">1006</a></span><span class="t"> <span class="key">for</span> <span class="nam">target</span> <span class="key">in</span> <span class="nam">node</span><span class="op">.</span><span class="nam">targets</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1089
- <p class="mis show_mis"><span class="n"><a id="t1007" href="#t1007">1007</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">target</span><span class="op">,</span> <span class="nam">ast</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>
1090
- <p class="mis show_mis"><span class="n"><a id="t1008" href="#t1008">1008</a></span><span class="t"> <span class="key">if</span> <span class="nam">target</span><span class="op">.</span><span class="nam">id</span> <span class="key">in</span> <span class="op">(</span><span class="str">'export'</span><span class="op">,</span> <span class="str">'resource_uri'</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1091
- <p class="mis show_mis"><span class="n"><a id="t1009" href="#t1009">1009</a></span><span class="t"> <span class="key">return</span> <span class="key">True</span>&nbsp;</span><span class="r"></span></p>
1092
- <p class="pln"><span class="n"><a id="t1010" href="#t1010">1010</a></span><span class="t">&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">return</span> <span class="key">False</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">&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="key">except</span> <span class="op">(</span><span class="nam">SyntaxError</span><span class="op">,</span> <span class="nam">OSError</span><span class="op">,</span> <span class="nam">UnicodeDecodeError</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="com"># If we can't parse the file, assume it's not a component</span>&nbsp;</span><span class="r"></span></p>
1097
- <p class="mis show_mis"><span class="n"><a id="t1015" href="#t1015">1015</a></span><span class="t"> <span class="key">return</span> <span class="key">False</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">&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">&nbsp;</span><span class="r"></span></p>
1100
- <p class="run"><span class="n"><a id="t1018" href="#t1018">1018</a></span><span class="t"><span class="key">def</span> <span class="nam">parse_shared_files</span><span class="op">(</span><span class="nam">project_path</span><span class="op">:</span> <span class="nam">Path</span><span class="op">)</span> <span class="op">-></span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</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>
1101
- <p class="pln"><span class="n"><a id="t1019" href="#t1019">1019</a></span><span class="t"> <span class="str">"""Find all shared Python files in the project (non-component .py files).</span>&nbsp;</span><span class="r"></span></p>
1102
- <p class="pln"><span class="n"><a id="t1020" href="#t1020">1020</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1103
- <p class="pln"><span class="n"><a id="t1021" href="#t1021">1021</a></span><span class="t"><span class="str"> Args:</span>&nbsp;</span><span class="r"></span></p>
1104
- <p class="pln"><span class="n"><a id="t1022" href="#t1022">1022</a></span><span class="t"><span class="str"> project_path: Path to the project root</span>&nbsp;</span><span class="r"></span></p>
1105
- <p class="pln"><span class="n"><a id="t1023" href="#t1023">1023</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1106
- <p class="pln"><span class="n"><a id="t1024" href="#t1024">1024</a></span><span class="t"><span class="str"> Returns:</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"><span class="str"> Dictionary mapping module paths to shared file paths</span>&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="str"> """</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">shared_files</span> <span class="op">=</span> <span class="op">{</span><span class="op">}</span>&nbsp;</span><span class="r"></span></p>
1110
- <p class="pln"><span class="n"><a id="t1028" href="#t1028">1028</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1111
- <p class="pln"><span class="n"><a id="t1029" href="#t1029">1029</a></span><span class="t"> <span class="com"># Search for all .py files in tools, resources, and prompts directories</span>&nbsp;</span><span class="r"></span></p>
1112
- <p class="mis show_mis"><span class="n"><a id="t1030" href="#t1030">1030</a></span><span class="t"> <span class="key">for</span> <span class="nam">dir_name</span> <span class="key">in</span> <span class="op">[</span><span class="str">"tools"</span><span class="op">,</span> <span class="str">"resources"</span><span class="op">,</span> <span class="str">"prompts"</span><span class="op">]</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1113
- <p class="mis show_mis"><span class="n"><a id="t1031" href="#t1031">1031</a></span><span class="t"> <span class="nam">base_dir</span> <span class="op">=</span> <span class="nam">project_path</span> <span class="op">/</span> <span class="nam">dir_name</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="key">if</span> <span class="key">not</span> <span class="nam">base_dir</span><span class="op">.</span><span class="nam">exists</span><span class="op">(</span><span class="op">)</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">base_dir</span><span class="op">.</span><span class="nam">is_dir</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"></span></p>
1115
- <p class="mis show_mis"><span class="n"><a id="t1033" href="#t1033">1033</a></span><span class="t"> <span class="key">continue</span>&nbsp;</span><span class="r"></span></p>
1116
- <p class="pln"><span class="n"><a id="t1034" href="#t1034">1034</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
1117
- <p class="pln"><span class="n"><a id="t1035" href="#t1035">1035</a></span><span class="t"> <span class="com"># Find all .py files (recursively)</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="key">for</span> <span class="nam">py_file</span> <span class="key">in</span> <span class="nam">base_dir</span><span class="op">.</span><span class="nam">glob</span><span class="op">(</span><span class="str">"**/*.py"</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"> <span class="com"># Skip files in __pycache__ or other hidden directories</span>&nbsp;</span><span class="r"></span></p>
1120
- <p class="mis show_mis"><span class="n"><a id="t1038" href="#t1038">1038</a></span><span class="t"> <span class="key">if</span> <span class="str">"__pycache__"</span> <span class="key">in</span> <span class="nam">py_file</span><span class="op">.</span><span class="nam">parts</span> <span class="key">or</span> <span class="nam">any</span><span class="op">(</span><span class="nam">part</span><span class="op">.</span><span class="nam">startswith</span><span class="op">(</span><span class="str">"."</span><span class="op">)</span> <span class="key">for</span> <span class="nam">part</span> <span class="key">in</span> <span class="nam">py_file</span><span class="op">.</span><span class="nam">parts</span><span class="op">)</span><span class="op">:</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="key">continue</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"># Skip files that are Golf components (have export or resource_uri)</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">_is_golf_component_file</span><span class="op">(</span><span class="nam">py_file</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="key">continue</span>&nbsp;</span><span class="r"></span></p>
1126
- <p class="pln"><span class="n"><a id="t1044" href="#t1044">1044</a></span><span class="t">&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"> <span class="com"># Calculate the module path for this shared file</span>&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"># For example: tools/weather/helpers.py -> tools/weather/helpers</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">relative_path</span> <span class="op">=</span> <span class="nam">py_file</span><span class="op">.</span><span class="nam">relative_to</span><span class="op">(</span><span class="nam">project_path</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="nam">module_path</span> <span class="op">=</span> <span class="nam">str</span><span class="op">(</span><span class="nam">relative_path</span><span class="op">.</span><span class="nam">with_suffix</span><span class="op">(</span><span class="str">''</span><span class="op">)</span><span class="op">)</span> <span class="com"># Remove .py extension</span>&nbsp;</span><span class="r"></span></p>
1131
- <p class="pln"><span class="n"><a id="t1049" href="#t1049">1049</a></span><span class="t">&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">shared_files</span><span class="op">[</span><span class="nam">module_path</span><span class="op">]</span> <span class="op">=</span> <span class="nam">py_file</span>&nbsp;</span><span class="r"></span></p>
1133
- <p class="pln"><span class="n"><a id="t1051" href="#t1051">1051</a></span><span class="t">&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="key">return</span> <span class="nam">shared_files</span>&nbsp;</span><span class="r"></span></p>
1135
- </main>
1136
- <footer>
1137
- <div class="content">
1138
- <p>
1139
- <a class="nav" href="z_7ba499ed22986217_config_py.html">&#xab; prev</a> &nbsp; &nbsp;
1140
- <a class="nav" href="index.html">&Hat; index</a> &nbsp; &nbsp;
1141
- <a class="nav" href="z_7ba499ed22986217_platform_py.html">&#xbb; next</a>
1142
- &nbsp; &nbsp; &nbsp;
1143
- <a class="nav" href="https://coverage.readthedocs.io/en/7.6.12">coverage.py v7.6.12</a>,
1144
- created at 2025-08-16 18:46 +0200
1145
- </p>
1146
- </div>
1147
- </footer>
1148
- </body>
1149
- </html>