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.
- {whatap_python-2.2.1 → whatap_python-2.2.2}/PKG-INFO +1 -1
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/__init__.py +66 -24
- whatap_python-2.2.2/whatap/build.py +4 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/native_process.py +55 -27
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/PKG-INFO +1 -1
- whatap_python-2.2.1/whatap/build.py +0 -4
- {whatap_python-2.2.1 → whatap_python-2.2.2}/README.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/pyproject.toml +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/setup.cfg +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/setup.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/LICENSE +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/README.rst +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/__main__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/darwin/amd64/whatap_python +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/darwin/arm64/whatap_python +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/linux/amd64/whatap_python +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/linux/arm64/whatap_python +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/agent/windows/whatap_python.exe +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/bootstrap/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/bootstrap/sitecustomize.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/configuration.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/configure.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/conf/license.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/control/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/counter_manager.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/base_task.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/llm_evaluator_task.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/llm_log_sink_task.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/llm_stat_task.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/counter/tasks/openfiledescriptor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/doctor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/io/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/io/data_inputx.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/io/data_outputx.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/agent_name.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/prompt_meta.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/session.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/turn.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/user.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/api/workflow.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/cut.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/guard.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/control/trajectory.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/definitions.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/base.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/_json_repair.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/answer_relevance.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/combined_judge.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/factuality.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/hallucination.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/judge_factories.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/llm_judge.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/pii_leak.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/prompt_injection.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/toxicity.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/url_scan.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/registry.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/sampler.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/scope.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/features.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/_boundary.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/agent.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/llm_api.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/instrument/workflow.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_input_message.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_log_sink_pack.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_output_message.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_step_eval_status.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_step_status.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_system_message.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_tool_calls.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_tool_results.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_tx_status.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/hermes/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/hermes/gateway.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/hermes/kanban.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/orchestration/langgraph/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/pricing.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/anthropic/messages/messages_stream.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/_content.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/converse/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/converse/converse_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/converse/converse_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/event_stream.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/http.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/invoke_model/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/invoke_model/invoke_model_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/invoke_model/invoke_model_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/runtime.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/bedrock/step.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/interceptor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/chat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/chat_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/chat/chat_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/completions.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/completions_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/completions/completions_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/content_parser.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/embeddings.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/embeddings_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/embeddings/embeddings_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/responses.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/responses_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/openai/responses/responses_extractor.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/stream_accumulator.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/providers/workflow.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/active_agent_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/active_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/actx_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/answer_relevance_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/api_status_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/base_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/combined_judge_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/error_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/factuality_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/feature_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/finish_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/hallucination_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/perf_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/pii_leak_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/prompt_injection_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/token_usage_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/toxicity_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/traj_actx_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/stats/url_scan_eval_stat.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/async_sender.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/packet_enum.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/packet_type_enum.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/param_def.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/stackhelper.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/udp_session.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/net/udp_thread.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/logSinkPack.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/pack.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/pack_enum.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/pack/tagCountPack.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/scripts/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/AGENTS.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/INSTALL.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/SKILL.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/config-keys.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/frameworks.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/llm-api-usage.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/llm-evaluation.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/llm-observability.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/skills/whatap-python-install/references/troubleshooting.md +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/amqp/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/amqp/kombu.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/amqp/pika.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/bottle.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/celery.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/cherrypy.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/django.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/django_asgi.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/django_py3.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/endpoint.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/exception_log.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/instrumentation.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/scope.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/fastapi/transaction.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/flask.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/frappe.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/graphql.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/nameko.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/odoo.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/starlette.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/tornado.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/application/wsgi.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/cxoracle.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/mongo.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/mysql.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/neo4j.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/psycopg2.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/psycopg3.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/redis.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/sqlalchemy.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/sqlite3.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/database/util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/email/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/email/smtp.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/hook_service_patterns.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/django.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/httplib.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/httpx.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/httpx2.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/requests.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/stream_end.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/urllib3.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/httpc/util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/logging.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/pattern_targets.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/plugin.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/process/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/process/subprocess_spawn.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/standalone/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/standalone/multiple.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/standalone/single.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/thread_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mod/workflow_plugin.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/mtrace_env.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/patch.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/simple_trace_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_context.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_context_manager.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_error.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_handler.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_import.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/trace/trace_module_definition.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/bit_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/hyperloglog.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/murmurhash.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/cardinality/registerset.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/compare_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/date_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/debug_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/escape_literal_sql.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/frame_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/hash_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/hexa32.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/int_set.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/ip_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/keygen.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/linked_list.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/linked_map.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/metering_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/request_double_queue.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/request_queue.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/string_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/throttle_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/util/userid_util.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/__init__.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/blob_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/boolean_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/decimal_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/double_summary.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/double_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/float_array.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/float_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/int_array.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/ip4_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/list_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/long_array.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/long_summary.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/map_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/null_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/number_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/summary_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/text_array.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/text_hash_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/text_value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/value.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/value/value_enum.py +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/whatap.conf +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/SOURCES.txt +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/dependency_links.txt +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/entry_points.txt +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/not-zip-safe +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/requires.txt +0 -0
- {whatap_python-2.2.1 → whatap_python-2.2.2}/whatap_python.egg-info/top_level.txt +0 -0
|
@@ -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
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
-
|
|
642
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
671
|
-
pid, exit_code, _native_agent_log_path()),
|
|
672
|
-
log_id='
|
|
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
|
|
681
|
-
log_id='
|
|
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
|
|
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
|
|
687
|
-
log_id='
|
|
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'):
|
|
@@ -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
|
-
|
|
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 = (
|
|
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(
|
|
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 =
|
|
176
|
+
port = default_port
|
|
165
177
|
if not 0 <= port <= 65535:
|
|
166
|
-
raise ValueError('native
|
|
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', '
|
|
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
|
-
|
|
225
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/answer_relevance.py
RENAMED
|
File without changes
|
{whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/combined_judge.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/judge_factories.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/evaluators/builtins/prompt_injection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{whatap_python-2.2.1 → whatap_python-2.2.2}/whatap/llm/log_sink_packs/llm_step_eval_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|