whatap-python 2.2.1__tar.gz → 2.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. {whatap_python-2.2.1 → whatap_python-2.2.2}/PKG-INFO +1 -1
  2. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/__init__.py +66 -24
  3. whatap_python-2.2.2/whatap/build.py +4 -0
  4. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/native_process.py +55 -27
  5. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/PKG-INFO +1 -1
  6. whatap_python-2.2.1/whatap/build.py +0 -4
  7. {whatap_python-2.2.1 → whatap_python-2.2.2}/README.md +0 -0
  8. {whatap_python-2.2.1 → whatap_python-2.2.2}/pyproject.toml +0 -0
  9. {whatap_python-2.2.1 → whatap_python-2.2.2}/setup.cfg +0 -0
  10. {whatap_python-2.2.1 → whatap_python-2.2.2}/setup.py +0 -0
  11. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/LICENSE +0 -0
  12. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/README.rst +0 -0
  13. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/__main__.py +0 -0
  14. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/darwin/amd64/whatap_python +0 -0
  15. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/darwin/arm64/whatap_python +0 -0
  16. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/linux/amd64/whatap_python +0 -0
  17. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/linux/arm64/whatap_python +0 -0
  18. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/windows/whatap_python.exe +0 -0
  19. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/bootstrap/__init__.py +0 -0
  20. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/bootstrap/sitecustomize.py +0 -0
  21. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/__init__.py +0 -0
  22. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/configuration.py +0 -0
  23. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/configure.py +0 -0
  24. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/license.py +0 -0
  25. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/control/__init__.py +0 -0
  26. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/__init__.py +0 -0
  27. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/counter_manager.py +0 -0
  28. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/__init__.py +0 -0
  29. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/base_task.py +0 -0
  30. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/llm_evaluator_task.py +0 -0
  31. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/llm_log_sink_task.py +0 -0
  32. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/llm_stat_task.py +0 -0
  33. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/openfiledescriptor.py +0 -0
  34. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/doctor.py +0 -0
  35. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/io/__init__.py +0 -0
  36. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/io/data_inputx.py +0 -0
  37. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/io/data_outputx.py +0 -0
  38. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/__init__.py +0 -0
  39. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/__init__.py +0 -0
  40. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/agent_name.py +0 -0
  41. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/prompt_meta.py +0 -0
  42. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/session.py +0 -0
  43. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/turn.py +0 -0
  44. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/user.py +0 -0
  45. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/workflow.py +0 -0
  46. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/__init__.py +0 -0
  47. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/cut.py +0 -0
  48. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/guard.py +0 -0
  49. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/trajectory.py +0 -0
  50. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/definitions.py +0 -0
  51. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/__init__.py +0 -0
  52. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/base.py +0 -0
  53. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/__init__.py +0 -0
  54. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/_json_repair.py +0 -0
  55. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/answer_relevance.py +0 -0
  56. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/combined_judge.py +0 -0
  57. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/factuality.py +0 -0
  58. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/hallucination.py +0 -0
  59. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/judge_factories.py +0 -0
  60. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/llm_judge.py +0 -0
  61. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/pii_leak.py +0 -0
  62. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/prompt_injection.py +0 -0
  63. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/toxicity.py +0 -0
  64. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/url_scan.py +0 -0
  65. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/registry.py +0 -0
  66. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/sampler.py +0 -0
  67. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/scope.py +0 -0
  68. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/features.py +0 -0
  69. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/__init__.py +0 -0
  70. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/_boundary.py +0 -0
  71. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/agent.py +0 -0
  72. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/llm_api.py +0 -0
  73. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/workflow.py +0 -0
  74. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/__init__.py +0 -0
  75. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_input_message.py +0 -0
  76. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_log_sink_pack.py +0 -0
  77. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_output_message.py +0 -0
  78. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_step_eval_status.py +0 -0
  79. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_step_status.py +0 -0
  80. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_system_message.py +0 -0
  81. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_tool_calls.py +0 -0
  82. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_tool_results.py +0 -0
  83. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_tx_status.py +0 -0
  84. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/__init__.py +0 -0
  85. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/hermes/__init__.py +0 -0
  86. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/hermes/gateway.py +0 -0
  87. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/hermes/kanban.py +0 -0
  88. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/langgraph/__init__.py +0 -0
  89. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/pricing.py +0 -0
  90. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/__init__.py +0 -0
  91. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/__init__.py +0 -0
  92. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/__init__.py +0 -0
  93. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages.py +0 -0
  94. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages_context.py +0 -0
  95. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages_extractor.py +0 -0
  96. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages_stream.py +0 -0
  97. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/__init__.py +0 -0
  98. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/_content.py +0 -0
  99. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/converse/__init__.py +0 -0
  100. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/converse/converse_context.py +0 -0
  101. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/converse/converse_extractor.py +0 -0
  102. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/event_stream.py +0 -0
  103. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/http.py +0 -0
  104. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/invoke_model/__init__.py +0 -0
  105. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/invoke_model/invoke_model_context.py +0 -0
  106. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/invoke_model/invoke_model_extractor.py +0 -0
  107. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/runtime.py +0 -0
  108. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/step.py +0 -0
  109. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/interceptor.py +0 -0
  110. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/__init__.py +0 -0
  111. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/__init__.py +0 -0
  112. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/chat.py +0 -0
  113. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/chat_context.py +0 -0
  114. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/chat_extractor.py +0 -0
  115. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/__init__.py +0 -0
  116. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/completions.py +0 -0
  117. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/completions_context.py +0 -0
  118. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/completions_extractor.py +0 -0
  119. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/content_parser.py +0 -0
  120. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/__init__.py +0 -0
  121. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/embeddings.py +0 -0
  122. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/embeddings_context.py +0 -0
  123. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/embeddings_extractor.py +0 -0
  124. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/__init__.py +0 -0
  125. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/responses.py +0 -0
  126. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/responses_context.py +0 -0
  127. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/responses_extractor.py +0 -0
  128. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/stream_accumulator.py +0 -0
  129. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/workflow.py +0 -0
  130. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/__init__.py +0 -0
  131. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/active_agent_stat.py +0 -0
  132. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/active_stat.py +0 -0
  133. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/actx_stat.py +0 -0
  134. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/answer_relevance_eval_stat.py +0 -0
  135. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/api_status_stat.py +0 -0
  136. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/base_stat.py +0 -0
  137. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/combined_judge_eval_stat.py +0 -0
  138. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/error_stat.py +0 -0
  139. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/eval_stat.py +0 -0
  140. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/factuality_eval_stat.py +0 -0
  141. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/feature_stat.py +0 -0
  142. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/finish_stat.py +0 -0
  143. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/hallucination_eval_stat.py +0 -0
  144. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/perf_stat.py +0 -0
  145. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/pii_leak_eval_stat.py +0 -0
  146. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/prompt_injection_eval_stat.py +0 -0
  147. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/token_usage_stat.py +0 -0
  148. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/toxicity_eval_stat.py +0 -0
  149. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/traj_actx_stat.py +0 -0
  150. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/url_scan_eval_stat.py +0 -0
  151. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/__init__.py +0 -0
  152. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/async_sender.py +0 -0
  153. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/packet_enum.py +0 -0
  154. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/packet_type_enum.py +0 -0
  155. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/param_def.py +0 -0
  156. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/stackhelper.py +0 -0
  157. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/udp_session.py +0 -0
  158. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/udp_thread.py +0 -0
  159. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/__init__.py +0 -0
  160. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/logSinkPack.py +0 -0
  161. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/pack.py +0 -0
  162. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/pack_enum.py +0 -0
  163. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/tagCountPack.py +0 -0
  164. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/scripts/__init__.py +0 -0
  165. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/AGENTS.md +0 -0
  166. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/INSTALL.md +0 -0
  167. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/SKILL.md +0 -0
  168. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/config-keys.md +0 -0
  169. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/frameworks.md +0 -0
  170. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/llm-api-usage.md +0 -0
  171. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/llm-evaluation.md +0 -0
  172. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/llm-observability.md +0 -0
  173. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/troubleshooting.md +0 -0
  174. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/__init__.py +0 -0
  175. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/__init__.py +0 -0
  176. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/amqp/__init__.py +0 -0
  177. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/amqp/kombu.py +0 -0
  178. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/amqp/pika.py +0 -0
  179. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/__init__.py +0 -0
  180. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/bottle.py +0 -0
  181. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/celery.py +0 -0
  182. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/cherrypy.py +0 -0
  183. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/django.py +0 -0
  184. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/django_asgi.py +0 -0
  185. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/django_py3.py +0 -0
  186. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/__init__.py +0 -0
  187. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/endpoint.py +0 -0
  188. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/exception_log.py +0 -0
  189. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/instrumentation.py +0 -0
  190. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/scope.py +0 -0
  191. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/transaction.py +0 -0
  192. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/flask.py +0 -0
  193. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/frappe.py +0 -0
  194. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/graphql.py +0 -0
  195. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/nameko.py +0 -0
  196. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/odoo.py +0 -0
  197. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/starlette.py +0 -0
  198. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/tornado.py +0 -0
  199. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/wsgi.py +0 -0
  200. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/__init__.py +0 -0
  201. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/cxoracle.py +0 -0
  202. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/mongo.py +0 -0
  203. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/mysql.py +0 -0
  204. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/neo4j.py +0 -0
  205. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/psycopg2.py +0 -0
  206. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/psycopg3.py +0 -0
  207. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/redis.py +0 -0
  208. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/sqlalchemy.py +0 -0
  209. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/sqlite3.py +0 -0
  210. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/util.py +0 -0
  211. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/email/__init__.py +0 -0
  212. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/email/smtp.py +0 -0
  213. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/hook_service_patterns.py +0 -0
  214. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/__init__.py +0 -0
  215. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/django.py +0 -0
  216. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/httplib.py +0 -0
  217. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/httpx.py +0 -0
  218. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/httpx2.py +0 -0
  219. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/requests.py +0 -0
  220. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/stream_end.py +0 -0
  221. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/urllib3.py +0 -0
  222. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/util.py +0 -0
  223. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/logging.py +0 -0
  224. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/pattern_targets.py +0 -0
  225. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/plugin.py +0 -0
  226. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/process/__init__.py +0 -0
  227. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/process/subprocess_spawn.py +0 -0
  228. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/standalone/__init__.py +0 -0
  229. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/standalone/multiple.py +0 -0
  230. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/standalone/single.py +0 -0
  231. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/thread_context.py +0 -0
  232. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/workflow_plugin.py +0 -0
  233. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mtrace_env.py +0 -0
  234. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/patch.py +0 -0
  235. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/simple_trace_context.py +0 -0
  236. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_context.py +0 -0
  237. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_context_manager.py +0 -0
  238. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_error.py +0 -0
  239. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_handler.py +0 -0
  240. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_import.py +0 -0
  241. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_module_definition.py +0 -0
  242. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/__init__.py +0 -0
  243. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/bit_util.py +0 -0
  244. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/__init__.py +0 -0
  245. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/hyperloglog.py +0 -0
  246. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/murmurhash.py +0 -0
  247. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/registerset.py +0 -0
  248. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/compare_util.py +0 -0
  249. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/date_util.py +0 -0
  250. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/debug_util.py +0 -0
  251. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/escape_literal_sql.py +0 -0
  252. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/frame_util.py +0 -0
  253. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/hash_util.py +0 -0
  254. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/hexa32.py +0 -0
  255. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/int_set.py +0 -0
  256. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/ip_util.py +0 -0
  257. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/keygen.py +0 -0
  258. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/linked_list.py +0 -0
  259. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/linked_map.py +0 -0
  260. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/metering_util.py +0 -0
  261. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/request_double_queue.py +0 -0
  262. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/request_queue.py +0 -0
  263. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/string_util.py +0 -0
  264. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/throttle_util.py +0 -0
  265. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/userid_util.py +0 -0
  266. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/__init__.py +0 -0
  267. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/blob_value.py +0 -0
  268. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/boolean_value.py +0 -0
  269. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/decimal_value.py +0 -0
  270. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/double_summary.py +0 -0
  271. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/double_value.py +0 -0
  272. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/float_array.py +0 -0
  273. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/float_value.py +0 -0
  274. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/int_array.py +0 -0
  275. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/ip4_value.py +0 -0
  276. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/list_value.py +0 -0
  277. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/long_array.py +0 -0
  278. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/long_summary.py +0 -0
  279. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/map_value.py +0 -0
  280. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/null_value.py +0 -0
  281. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/number_value.py +0 -0
  282. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/summary_value.py +0 -0
  283. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/text_array.py +0 -0
  284. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/text_hash_value.py +0 -0
  285. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/text_value.py +0 -0
  286. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/value.py +0 -0
  287. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/value_enum.py +0 -0
  288. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/whatap.conf +0 -0
  289. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/SOURCES.txt +0 -0
  290. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/dependency_links.txt +0 -0
  291. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/entry_points.txt +0 -0
  292. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/not-zip-safe +0 -0
  293. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/requires.txt +0 -0
  294. {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: whatap-python
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: Monitoring and Profiling Service
5
5
  Home-page: https://www.whatap.io
6
6
  Author: whatap
@@ -562,9 +562,13 @@ def agent():
562
562
  llm_accesskey = (preview_whatap_conf("llm_accesskey")
563
563
  or os.environ.get("llm_accesskey"))
564
564
  if llm_accesskey:
565
- t = threading.Thread(target=go, kwargs={'llm': True})
566
- t.setDaemon(True)
567
- t.start()
565
+ if sys.platform.startswith('linux'):
566
+ # APM 과 같은 이유로 소유 기록까지 호출 스레드에서 끝낸다.
567
+ go(llm=True)
568
+ else:
569
+ t = threading.Thread(target=go, kwargs={'llm': True})
570
+ t.setDaemon(True)
571
+ t.start()
568
572
  else:
569
573
  whatap_print("WHATAP: llm_enabled=true 이나 llm_accesskey 가 "
570
574
  "없어 LLM 에이전트 기동을 건너뜁니다")
@@ -636,24 +640,31 @@ def llm_agent_path():
636
640
 
637
641
 
638
642
 
639
- def _native_agent_spec(opts):
640
- from whatap.util.native_process import AgentSpec
641
- source = os.path.join(os.path.dirname(__file__), 'agent', 'linux',
642
- ARCH[platform.machine()], AGENT_NAME)
643
+ def _native_agent_spec(opts, llm_executable=None):
644
+ from whatap.util.native_process import APM, LLM, AgentSpec
645
+ if llm_executable:
646
+ # LLM 은 llm_agent_path() 의 전용 바이너리를 제자리에서 실행한다(@see _start_go).
647
+ source, mode = llm_executable, LLM
648
+ else:
649
+ source = os.path.join(os.path.dirname(__file__), 'agent', 'linux',
650
+ ARCH[platform.machine()], AGENT_NAME)
651
+ mode = APM
643
652
  env = os.environ.copy()
644
653
  env.update(opts)
645
- return AgentSpec(os.environ['WHATAP_HOME'], source, env)
654
+ return AgentSpec(os.environ['WHATAP_HOME'], source, env, mode=mode)
646
655
 
647
656
 
648
- def _native_agent_log_path():
649
- return os.path.join(os.environ.get('WHATAP_HOME', '.'), 'logs', AGENT_NAME + '.log')
657
+ def _native_agent_log_path(llm=False):
658
+ # LLM 은 별개 프로세스라 기동 실패 원인이 APM 로그와 섞이지 않게 나눈다.
659
+ name = AGENT_NAME + ('.llm.log' if llm else '.log')
660
+ return os.path.join(os.environ.get('WHATAP_HOME', '.'), 'logs', name)
650
661
 
651
662
 
652
- def _open_native_agent_log():
663
+ def _open_native_agent_log(llm=False):
653
664
  # managed 경로는 PIPE 를 읽지 않으므로 네이티브 stdout/stderr 를 파일로 남겨
654
665
  # 기동 직후 실패 원인을 추적할 수 있게 한다.
655
666
  try:
656
- log_path = _native_agent_log_path()
667
+ log_path = _native_agent_log_path(llm)
657
668
  os.makedirs(os.path.dirname(log_path), exist_ok=True)
658
669
  return open(log_path, 'ab')
659
670
  except Exception as e:
@@ -662,29 +673,40 @@ def _open_native_agent_log():
662
673
 
663
674
 
664
675
  def go(batch=False, opts={}, llm=False):
665
- if sys.platform.startswith('linux') and not batch and not llm:
676
+ if sys.platform.startswith('linux') and not batch:
666
677
  from whatap.util.native_process import FAILED, ensure_agent_running
678
+ label = 'LLM' if llm else 'APM'
679
+ log_prefix = 'WHATAP_LLM_AGENT' if llm else 'WHATAP_AGENT'
680
+ llm_executable = None
681
+ if llm:
682
+ # 바이너리가 없으면 락·/proc 탐색 전에 기존처럼 건너뛴다.
683
+ llm_executable, reason = llm_agent_path()
684
+ if llm_executable is None:
685
+ whatap_error_log(
686
+ 'WHATAP: skipping LLM agent start — {0}'.format(reason),
687
+ log_id='WHATAP_LLM_AGENT_UNAVAILABLE')
688
+ return
667
689
 
668
690
  def on_child_exit(pid, exit_code):
669
691
  whatap_error_log(
670
- 'WHATAP: native APM exited (PID: {}, exit code: {}, log: {})'.format(
671
- pid, exit_code, _native_agent_log_path()),
672
- log_id='WHATAP_AGENT_EXITED')
692
+ 'WHATAP: native {} exited (PID: {}, exit code: {}, log: {})'.format(
693
+ label, pid, exit_code, _native_agent_log_path(llm)),
694
+ log_id=log_prefix + '_EXITED')
673
695
 
674
696
  try:
675
- spec = _native_agent_spec(opts)
697
+ spec = _native_agent_spec(opts, llm_executable)
676
698
  result = ensure_agent_running(
677
699
  spec, lambda: _start_go(batch, opts, llm, managed=True),
678
700
  on_child_exit=on_child_exit)
679
701
  if result.status == FAILED:
680
- whatap_error_log('WHATAP: native APM startup failed',
681
- log_id='WHATAP_AGENT_START_FAILED')
702
+ whatap_error_log('WHATAP: native {} startup failed'.format(label),
703
+ log_id=log_prefix + '_START_FAILED')
682
704
  else:
683
- whatap_print('WHATAP: native APM {} (PID: {})'.format(
684
- result.status, result.pid))
705
+ whatap_print('WHATAP: native {} {} (PID: {})'.format(
706
+ label, result.status, result.pid))
685
707
  except Exception as e:
686
- whatap_error_log('WHATAP: native APM startup failed: {}'.format(e),
687
- log_id='WHATAP_AGENT_START_FAILED')
708
+ whatap_error_log('WHATAP: native {} startup failed: {}'.format(label, e),
709
+ log_id=log_prefix + '_START_FAILED')
688
710
  return
689
711
  return _start_go(batch, opts, llm)
690
712
 
@@ -895,7 +917,7 @@ def _start_go(batch=False, opts={}, llm=False, managed=False):
895
917
  creationflags=DETACHED_PROCESS,
896
918
  stdout=subprocess.PIPE, stderr=subprocess.PIPE)
897
919
  elif managed:
898
- go_out = _open_native_agent_log()
920
+ go_out = _open_native_agent_log(llm)
899
921
  try:
900
922
  process = subprocess.Popen(cmd_args,
901
923
  cwd=home_path, env=newenv,
@@ -1250,6 +1272,26 @@ def _config_port():
1250
1272
 
1251
1273
 
1252
1274
  def configLlmPort():
1275
+ if sys.platform.startswith('linux') and preview_whatap_conf('llm_enabled') == 'true':
1276
+ # 바이너리가 없으면 go(llm=True) 도 건너뛰므로 지킬 LLM 에이전트가 없다.
1277
+ llm_executable = llm_agent_path()[0]
1278
+ if llm_executable:
1279
+ from whatap.util.native_process import LLM, acquire_start_lock, configured_channel, find_existing_agent
1280
+ try:
1281
+ spec = _native_agent_spec({}, llm_executable)
1282
+ with acquire_start_lock(spec):
1283
+ if find_existing_agent(spec):
1284
+ # configPort() 와 같은 계약: 살아 있는 LLM 에이전트의 채널을 다시 쓰지 않는다.
1285
+ return configured_channel(spec.home, spec.environment,
1286
+ include_unix=False, mode=LLM)[1]
1287
+ return _config_llm_port()
1288
+ except Exception as e:
1289
+ # 락 타임아웃/다중 인스턴스 등은 CLI 를 죽이지 말고 기존 포트 할당으로 폴백
1290
+ whatap_print('WHATAP: live LLM agent check skipped, falling back to port file: %s' % e)
1291
+ return _config_llm_port()
1292
+
1293
+
1294
+ def _config_llm_port():
1253
1295
  # force_llm_net_udp_port가 설정된 경우 lock 파일 무시하고 해당 포트 강제 사용
1254
1296
  force_port_str = preview_whatap_conf("force_llm_net_udp_port")
1255
1297
  if force_port_str and force_port_str not in ('false', 'False'):
@@ -0,0 +1,4 @@
1
+ app = 'Python'
2
+ name = 'whatap-python'
3
+ version = '2.2.2'
4
+ release_date = '20261019'
@@ -1,4 +1,4 @@
1
- """Linux APM native process ownership (not instrumentation configuration)."""
1
+ """Linux APM/LLM native process ownership (not instrumentation configuration)."""
2
2
  import os
3
3
  import errno
4
4
  import fcntl
@@ -23,12 +23,22 @@ DISCOVERY_TIMEOUT_SECONDS = 1.0
23
23
  LOCK_TIMEOUT_SECONDS = 1.0
24
24
  LOCK_RETRY_SECONDS = 0.01
25
25
  DEFAULT_UDP_PORT = 6600
26
+ DEFAULT_LLM_UDP_PORT = 6700
26
27
  CONFIG_MAX_BYTES = 1024 * 1024
27
28
  RECORD_MAX_BYTES = 8192
28
29
  CHILD_STOP_TIMEOUT_SECONDS = 2.0
29
30
  STARTUP_GRACE_SECONDS = 0.5
30
31
  STARTUP_POLL_SECONDS = 0.05
31
32
  _TRUE_VALUES = ('1', 't', 'T', 'true', 'TRUE', 'True')
33
+ APM = 'apm'
34
+ LLM = 'llm'
35
+ # The same native binary name serves both modes. --llm switches only the UDP
36
+ # listener key (Go Config.go: LLMMode reads llm_net_udp_port); unix_socket keys
37
+ # are shared. Values: native key, its uppercase ENV alias, native default.
38
+ _UDP_PORT_KEYS = {APM: ('net_udp_port', 'WHATAP_NET_UDP_PORT', DEFAULT_UDP_PORT),
39
+ LLM: ('llm_net_udp_port', 'WHATAP_LLM_NET_UDP_PORT', DEFAULT_LLM_UDP_PORT)}
40
+ # Exactly the arguments the native pre-scan accepts as LLM mode.
41
+ _LLM_FLAGS = (b'--llm', b'-llm')
32
42
  _watchers = set()
33
43
  _watchers_lock = threading.Lock()
34
44
  _start_lock_fds = set()
@@ -106,14 +116,15 @@ def watch_owned_child(pid, process=None, on_exit=None):
106
116
  raise
107
117
 
108
118
 
109
- def configured_channel(home, env, include_unix=True):
119
+ def configured_channel(home, env, include_unix=True, mode=APM):
110
120
  """Read only native transport keys, including native file/ENV precedence.
111
121
 
112
122
  whatap.port is an object identity input, NOT the UDP listener port.
113
123
  """
114
- aliases = {'net_udp_port': 'WHATAP_NET_UDP_PORT',
124
+ port_key, port_alias, default_port = _UDP_PORT_KEYS[mode]
125
+ aliases = {port_key: port_alias,
115
126
  'use_env_first': 'WHATAP_USE_ENV_FIRST'}
116
- keys = ('net_udp_port', 'use_env_first', 'unix_socket_enabled', 'unix_socket')
127
+ keys = (port_key, 'use_env_first', 'unix_socket_enabled', 'unix_socket')
117
128
  config_home = env.get('WHATAP_CONFIG_HOME') or home
118
129
  config_name = env.get('WHATAP_CONFIG') or 'whatap.conf'
119
130
  # Preserve Go path.Join semantics before resolving against native cwd.
@@ -149,11 +160,12 @@ def configured_channel(home, env, include_unix=True):
149
160
  return value or default
150
161
 
151
162
  if include_unix and get('unix_socket_enabled', 'false') in _TRUE_VALUES:
152
- # Go path.Join joins even a leading slash in its second argument.
163
+ # Go path.Join joins even a leading slash in its second argument. LLM
164
+ # mode binds this same path, so an APM-owned socket makes it occupied.
153
165
  path = os.path.normpath(home + '/' + get('unix_socket', 'whatap.sock'))
154
166
  return ('unix', path)
155
167
  try:
156
- value = get('net_udp_port', str(DEFAULT_UDP_PORT))
168
+ value = get(port_key, str(default_port))
157
169
  # Native strconv.ParseInt(value, 10, 32) rejects Python-only syntax.
158
170
  if re.fullmatch(r'[+-]?[0-9]+', value) is None:
159
171
  raise ValueError('invalid native decimal')
@@ -161,9 +173,9 @@ def configured_channel(home, env, include_unix=True):
161
173
  if not -2147483648 <= port <= 2147483647:
162
174
  raise ValueError('native decimal exceeds int32')
163
175
  except ValueError:
164
- port = DEFAULT_UDP_PORT
176
+ port = default_port
165
177
  if not 0 <= port <= 65535:
166
- raise ValueError('native APM UDP port is out of range')
178
+ raise ValueError('native {} UDP port is out of range'.format(mode.upper()))
167
179
  return ('udp', port)
168
180
 
169
181
 
@@ -207,22 +219,34 @@ def owns_socket(pid, inodes):
207
219
 
208
220
 
209
221
  class AgentSpec(object):
210
- def __init__(self, home, executable, env=None):
222
+ def __init__(self, home, executable, env=None, mode=APM):
223
+ if mode not in _UDP_PORT_KEYS:
224
+ raise ValueError('unknown native agent mode: {!r}'.format(mode))
225
+ self.mode = mode
226
+ self.label = mode.upper()
211
227
  self.home = os.path.realpath(home)
212
228
  self.executable = os.path.realpath(executable)
213
229
  environment = os.environ if env is None else env
214
230
  # Retain only transport/config-location keys, never credentials.
215
231
  self.environment = {key: environment[key] for key in (
216
- 'net_udp_port', 'WHATAP_NET_UDP_PORT', 'use_env_first',
232
+ 'net_udp_port', 'WHATAP_NET_UDP_PORT', 'llm_net_udp_port',
233
+ 'WHATAP_LLM_NET_UDP_PORT', 'use_env_first',
217
234
  'WHATAP_USE_ENV_FIRST', 'unix_socket_enabled', 'unix_socket',
218
235
  'WHATAP_CONFIG_HOME', 'WHATAP_CONFIG') if key in environment}
219
236
  self.channel = None # Read under the startup lock, not before waiting.
220
- self.pid_file = Path(self.home) / 'whatap_python.pid'
221
237
  namespaces = '{}-{}'.format(os.stat('/proc/self/ns/pid').st_ino,
222
238
  os.stat('/proc/self/ns/net').st_ino)
223
239
  self.namespaces = namespaces
224
- self.lock_file = Path(self.home) / ('whatap_python.' + namespaces + '.lock')
225
- self.record_file = Path(self.home) / ('whatap_python.' + namespaces + '.runtime.json')
240
+ # APM file names predate LLM support. LLM keeps its legacy PID file name
241
+ # and never shares a lock/record with APM: the modes start independently.
242
+ if mode == APM:
243
+ self.pid_file = Path(self.home) / 'whatap_python.pid'
244
+ prefix = 'whatap_python.'
245
+ else:
246
+ self.pid_file = Path(self.home) / 'whatap_python.pid.llm'
247
+ prefix = 'whatap_python.llm.'
248
+ self.lock_file = Path(self.home) / (prefix + namespaces + '.lock')
249
+ self.record_file = Path(self.home) / (prefix + namespaces + '.runtime.json')
226
250
 
227
251
 
228
252
  def _process_stat(pid):
@@ -237,7 +261,7 @@ def _read_record(spec):
237
261
  with spec.record_file.open() as stream:
238
262
  content = stream.read(RECORD_MAX_BYTES + 1)
239
263
  if len(content) > RECORD_MAX_BYTES:
240
- raise RuntimeError('native APM ownership record is too large')
264
+ raise RuntimeError('native {} ownership record is too large'.format(spec.label))
241
265
  value = json.loads(content)
242
266
  return value if isinstance(value, dict) else {}
243
267
  except (FileNotFoundError, ValueError):
@@ -260,7 +284,7 @@ def _atomic_write(path, content):
260
284
  def write_runtime_record(spec, pid):
261
285
  info = _process_stat(pid)
262
286
  if info['state'] in ('Z', 'X'):
263
- raise RuntimeError('native APM exited during startup')
287
+ raise RuntimeError('native {} exited during startup'.format(spec.label))
264
288
  record = {'pid': pid, 'start_time': info['start_time'],
265
289
  'channel': list(spec.channel), 'namespaces': spec.namespaces}
266
290
  if _read_record(spec) != record:
@@ -290,7 +314,7 @@ def acquire_start_lock(spec):
290
314
  try:
291
315
  info = os.fstat(fd)
292
316
  if not stat.S_ISREG(info.st_mode) or info.st_nlink != 1:
293
- raise RuntimeError('unsafe native APM lock file')
317
+ raise RuntimeError('unsafe native {} lock file'.format(spec.label))
294
318
  deadline = time.monotonic() + LOCK_TIMEOUT_SECONDS
295
319
  while True:
296
320
  try:
@@ -300,7 +324,7 @@ def acquire_start_lock(spec):
300
324
  if error.errno not in (errno.EAGAIN, errno.EACCES):
301
325
  raise
302
326
  if time.monotonic() >= deadline:
303
- raise TimeoutError('native APM startup lock is busy')
327
+ raise TimeoutError('native {} startup lock is busy'.format(spec.label))
304
328
  time.sleep(LOCK_RETRY_SECONDS)
305
329
  yield
306
330
  finally:
@@ -324,7 +348,8 @@ def _matching_process(pid, spec, record):
324
348
  if os.path.realpath(os.readlink(str(root / 'cwd'))) != spec.home:
325
349
  return False
326
350
  args = (root / 'cmdline').read_bytes().split(b'\0')
327
- if b'--llm' in args:
351
+ if any(flag in args for flag in _LLM_FLAGS) != (spec.mode == LLM):
352
+ # APM and LLM share the name and home; never adopt the other mode.
328
353
  return False
329
354
  namespaces = '{}-{}'.format(os.stat(str(root / 'ns/pid')).st_ino,
330
355
  os.stat(str(root / 'ns/net')).st_ino)
@@ -332,17 +357,20 @@ def _matching_process(pid, spec, record):
332
357
  return False
333
358
  process_exe = str(root / 'exe')
334
359
  same_binary = os.path.samefile(process_exe, spec.executable)
335
- if not same_binary and os.path.realpath(os.readlink(process_exe)) == os.path.join(spec.home, 'whatap_python'):
360
+ if (not same_binary and spec.mode == APM and
361
+ os.path.realpath(os.readlink(process_exe)) == os.path.join(spec.home, 'whatap_python')):
336
362
  # _start_go copies when the filesystem does not support symlinks.
337
363
  # Path/name alone is insufficient: compare the actual executable.
338
364
  same_binary = filecmp.cmp(process_exe, spec.executable, shallow=False)
339
365
  if not same_binary:
340
366
  if (root / 'comm').read_text().strip() == 'whatap_python':
341
- raise RuntimeError('different native APM executable is already running in this home')
367
+ raise RuntimeError('different native {} executable is already running in this home'.format(
368
+ spec.label))
342
369
  return False
343
370
  if record.get('pid') == pid and record.get('start_time') == info['start_time']:
344
371
  if record.get('channel') != list(spec.channel):
345
- raise RuntimeError('running native APM channel differs from current configuration')
372
+ raise RuntimeError('running native {} channel differs from current configuration'.format(
373
+ spec.label))
346
374
  return True
347
375
  except (FileNotFoundError, ProcessLookupError):
348
376
  return False
@@ -350,7 +378,7 @@ def _matching_process(pid, spec, record):
350
378
 
351
379
  def find_existing_agent(spec):
352
380
  """Caller holds acquire_start_lock, including during port-file allocation."""
353
- spec.channel = configured_channel(spec.home, spec.environment)
381
+ spec.channel = configured_channel(spec.home, spec.environment, mode=spec.mode)
354
382
  record = _read_record(spec)
355
383
  recorded_pid = record.get('pid')
356
384
  if isinstance(recorded_pid, int) and recorded_pid > 0:
@@ -367,7 +395,7 @@ def find_existing_agent(spec):
367
395
  with os.scandir('/proc') as entries:
368
396
  for entry in entries:
369
397
  if time.monotonic() > deadline:
370
- raise RuntimeError('native APM process discovery timed out')
398
+ raise RuntimeError('native {} process discovery timed out'.format(spec.label))
371
399
  if not entry.name.isdigit():
372
400
  continue
373
401
  try:
@@ -380,7 +408,7 @@ def find_existing_agent(spec):
380
408
  except (FileNotFoundError, ProcessLookupError):
381
409
  continue
382
410
  if len(matches) > 1:
383
- raise RuntimeError('multiple native APM instances already exist')
411
+ raise RuntimeError('multiple native {} instances already exist'.format(spec.label))
384
412
  return matches[0] if matches else None
385
413
 
386
414
 
@@ -419,7 +447,7 @@ def _ensure_locked(spec, spawn, on_child_exit=None):
419
447
  pid = find_existing_agent(spec)
420
448
  occupied = channel_socket_inodes(spec.channel)
421
449
  if occupied and (not pid or not owns_socket(pid, occupied)):
422
- raise RuntimeError('native APM channel is occupied by another process')
450
+ raise RuntimeError('native {} channel is occupied by another process'.format(spec.label))
423
451
  if pid:
424
452
  previous = _read_record(spec)
425
453
  known = (previous.get('pid') == pid and
@@ -439,8 +467,8 @@ def _ensure_locked(spec, spawn, on_child_exit=None):
439
467
  return StartResult(FAILED, None)
440
468
  exit_code = _early_exit_code(process)
441
469
  if exit_code is not None:
442
- raise RuntimeError('native APM exited immediately (PID {}, exit code {})'.format(
443
- process.pid, exit_code))
470
+ raise RuntimeError('native {} exited immediately (PID {}, exit code {})'.format(
471
+ spec.label, process.pid, exit_code))
444
472
  try:
445
473
  record = write_runtime_record(spec, process.pid)
446
474
  watch_owned_child(process.pid, process,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: whatap-python
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: Monitoring and Profiling Service
5
5
  Home-page: https://www.whatap.io
6
6
  Author: whatap
@@ -1,4 +0,0 @@
1
- app = 'Python'
2
- name = 'whatap-python'
3
- version = '2.2.1'
4
- release_date = '20260929'
File without changes
File without changes
File without changes