llama-stack 0.3.5__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llama_stack/__init__.py +0 -5
- llama_stack/cli/llama.py +3 -3
- llama_stack/cli/stack/_list_deps.py +12 -23
- llama_stack/cli/stack/list_stacks.py +37 -18
- llama_stack/cli/stack/run.py +121 -11
- llama_stack/cli/stack/utils.py +0 -127
- llama_stack/core/access_control/access_control.py +69 -28
- llama_stack/core/access_control/conditions.py +15 -5
- llama_stack/core/admin.py +267 -0
- llama_stack/core/build.py +6 -74
- llama_stack/core/client.py +1 -1
- llama_stack/core/configure.py +6 -6
- llama_stack/core/conversations/conversations.py +28 -25
- llama_stack/core/datatypes.py +271 -79
- llama_stack/core/distribution.py +15 -16
- llama_stack/core/external.py +3 -3
- llama_stack/core/inspect.py +98 -15
- llama_stack/core/library_client.py +73 -61
- llama_stack/core/prompts/prompts.py +12 -11
- llama_stack/core/providers.py +17 -11
- llama_stack/core/resolver.py +65 -56
- llama_stack/core/routers/__init__.py +8 -12
- llama_stack/core/routers/datasets.py +1 -4
- llama_stack/core/routers/eval_scoring.py +7 -4
- llama_stack/core/routers/inference.py +55 -271
- llama_stack/core/routers/safety.py +52 -24
- llama_stack/core/routers/tool_runtime.py +6 -48
- llama_stack/core/routers/vector_io.py +130 -51
- llama_stack/core/routing_tables/benchmarks.py +24 -20
- llama_stack/core/routing_tables/common.py +1 -4
- llama_stack/core/routing_tables/datasets.py +22 -22
- llama_stack/core/routing_tables/models.py +119 -6
- llama_stack/core/routing_tables/scoring_functions.py +7 -7
- llama_stack/core/routing_tables/shields.py +1 -2
- llama_stack/core/routing_tables/toolgroups.py +17 -7
- llama_stack/core/routing_tables/vector_stores.py +51 -16
- llama_stack/core/server/auth.py +5 -3
- llama_stack/core/server/auth_providers.py +36 -20
- llama_stack/core/server/fastapi_router_registry.py +84 -0
- llama_stack/core/server/quota.py +2 -2
- llama_stack/core/server/routes.py +79 -27
- llama_stack/core/server/server.py +102 -87
- llama_stack/core/stack.py +201 -58
- llama_stack/core/storage/datatypes.py +26 -3
- llama_stack/{providers/utils → core/storage}/kvstore/__init__.py +2 -0
- llama_stack/{providers/utils → core/storage}/kvstore/kvstore.py +55 -24
- llama_stack/{providers/utils → core/storage}/kvstore/mongodb/mongodb.py +13 -10
- llama_stack/{providers/utils → core/storage}/kvstore/postgres/postgres.py +28 -17
- llama_stack/{providers/utils → core/storage}/kvstore/redis/redis.py +41 -16
- llama_stack/{providers/utils → core/storage}/kvstore/sqlite/sqlite.py +1 -1
- llama_stack/core/storage/sqlstore/__init__.py +17 -0
- llama_stack/{providers/utils → core/storage}/sqlstore/authorized_sqlstore.py +69 -49
- llama_stack/{providers/utils → core/storage}/sqlstore/sqlalchemy_sqlstore.py +47 -17
- llama_stack/{providers/utils → core/storage}/sqlstore/sqlstore.py +25 -8
- llama_stack/core/store/registry.py +1 -1
- llama_stack/core/utils/config.py +8 -2
- llama_stack/core/utils/config_resolution.py +32 -29
- llama_stack/core/utils/context.py +4 -10
- llama_stack/core/utils/exec.py +9 -0
- llama_stack/core/utils/type_inspection.py +45 -0
- llama_stack/distributions/dell/{run.yaml → config.yaml} +3 -2
- llama_stack/distributions/dell/dell.py +2 -2
- llama_stack/distributions/dell/run-with-safety.yaml +3 -2
- llama_stack/distributions/meta-reference-gpu/{run.yaml → config.yaml} +3 -2
- llama_stack/distributions/meta-reference-gpu/meta_reference.py +2 -2
- llama_stack/distributions/meta-reference-gpu/run-with-safety.yaml +3 -2
- llama_stack/distributions/nvidia/{run.yaml → config.yaml} +4 -4
- llama_stack/distributions/nvidia/nvidia.py +1 -1
- llama_stack/distributions/nvidia/run-with-safety.yaml +4 -4
- llama_stack/{apis/datasetio → distributions/oci}/__init__.py +1 -1
- llama_stack/distributions/oci/config.yaml +134 -0
- llama_stack/distributions/oci/oci.py +108 -0
- llama_stack/distributions/open-benchmark/{run.yaml → config.yaml} +5 -4
- llama_stack/distributions/open-benchmark/open_benchmark.py +2 -3
- llama_stack/distributions/postgres-demo/{run.yaml → config.yaml} +4 -3
- llama_stack/distributions/starter/{run.yaml → config.yaml} +64 -13
- llama_stack/distributions/starter/run-with-postgres-store.yaml +64 -13
- llama_stack/distributions/starter/starter.py +8 -5
- llama_stack/distributions/starter-gpu/{run.yaml → config.yaml} +64 -13
- llama_stack/distributions/starter-gpu/run-with-postgres-store.yaml +64 -13
- llama_stack/distributions/template.py +13 -69
- llama_stack/distributions/watsonx/{run.yaml → config.yaml} +4 -3
- llama_stack/distributions/watsonx/watsonx.py +1 -1
- llama_stack/log.py +28 -11
- llama_stack/models/llama/checkpoint.py +6 -6
- llama_stack/models/llama/hadamard_utils.py +2 -0
- llama_stack/models/llama/llama3/generation.py +3 -1
- llama_stack/models/llama/llama3/interface.py +2 -5
- llama_stack/models/llama/llama3/multimodal/encoder_utils.py +3 -3
- llama_stack/models/llama/llama3/multimodal/image_transform.py +6 -6
- llama_stack/models/llama/llama3/prompt_templates/system_prompts.py +1 -1
- llama_stack/models/llama/llama3/tool_utils.py +2 -1
- llama_stack/models/llama/llama4/prompt_templates/system_prompts.py +1 -1
- llama_stack/providers/inline/agents/meta_reference/__init__.py +3 -3
- llama_stack/providers/inline/agents/meta_reference/agents.py +44 -261
- llama_stack/providers/inline/agents/meta_reference/config.py +6 -1
- llama_stack/providers/inline/agents/meta_reference/responses/openai_responses.py +207 -57
- llama_stack/providers/inline/agents/meta_reference/responses/streaming.py +308 -47
- llama_stack/providers/inline/agents/meta_reference/responses/tool_executor.py +162 -96
- llama_stack/providers/inline/agents/meta_reference/responses/types.py +23 -8
- llama_stack/providers/inline/agents/meta_reference/responses/utils.py +201 -33
- llama_stack/providers/inline/agents/meta_reference/safety.py +8 -13
- llama_stack/providers/inline/batches/reference/__init__.py +2 -4
- llama_stack/providers/inline/batches/reference/batches.py +78 -60
- llama_stack/providers/inline/datasetio/localfs/datasetio.py +2 -5
- llama_stack/providers/inline/eval/meta_reference/eval.py +16 -61
- llama_stack/providers/inline/files/localfs/files.py +37 -28
- llama_stack/providers/inline/inference/meta_reference/config.py +2 -2
- llama_stack/providers/inline/inference/meta_reference/generators.py +50 -60
- llama_stack/providers/inline/inference/meta_reference/inference.py +403 -19
- llama_stack/providers/inline/inference/meta_reference/model_parallel.py +7 -26
- llama_stack/providers/inline/inference/meta_reference/parallel_utils.py +2 -12
- llama_stack/providers/inline/inference/sentence_transformers/sentence_transformers.py +10 -15
- llama_stack/providers/inline/post_training/common/validator.py +1 -5
- llama_stack/providers/inline/post_training/huggingface/post_training.py +8 -8
- llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device.py +18 -10
- llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device_dpo.py +12 -9
- llama_stack/providers/inline/post_training/huggingface/utils.py +27 -6
- llama_stack/providers/inline/post_training/torchtune/common/checkpointer.py +1 -1
- llama_stack/providers/inline/post_training/torchtune/common/utils.py +1 -1
- llama_stack/providers/inline/post_training/torchtune/datasets/format_adapter.py +1 -1
- llama_stack/providers/inline/post_training/torchtune/post_training.py +8 -8
- llama_stack/providers/inline/post_training/torchtune/recipes/lora_finetuning_single_device.py +16 -16
- llama_stack/providers/inline/safety/code_scanner/code_scanner.py +13 -9
- llama_stack/providers/inline/safety/llama_guard/llama_guard.py +18 -15
- llama_stack/providers/inline/safety/prompt_guard/prompt_guard.py +9 -9
- llama_stack/providers/inline/scoring/basic/scoring.py +6 -13
- llama_stack/providers/inline/scoring/basic/scoring_fn/docvqa_scoring_fn.py +1 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/equality_scoring_fn.py +1 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/docvqa.py +2 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/equality.py +2 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/ifeval.py +2 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/regex_parser_math_response.py +2 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/regex_parser_multiple_choice_answer.py +2 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/subset_of.py +2 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/ifeval_scoring_fn.py +1 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/regex_parser_math_response_scoring_fn.py +1 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/regex_parser_scoring_fn.py +1 -2
- llama_stack/providers/inline/scoring/basic/scoring_fn/subset_of_scoring_fn.py +1 -2
- llama_stack/providers/inline/scoring/braintrust/braintrust.py +12 -15
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/answer_correctness.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/answer_relevancy.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/answer_similarity.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_entity_recall.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_precision.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_recall.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_relevancy.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/factuality.py +2 -2
- llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/faithfulness.py +2 -2
- llama_stack/providers/inline/scoring/llm_as_judge/scoring.py +7 -14
- llama_stack/providers/inline/scoring/llm_as_judge/scoring_fn/fn_defs/llm_as_judge_405b_simpleqa.py +2 -2
- llama_stack/providers/inline/scoring/llm_as_judge/scoring_fn/fn_defs/llm_as_judge_base.py +1 -2
- llama_stack/providers/inline/scoring/llm_as_judge/scoring_fn/llm_as_judge_scoring_fn.py +1 -3
- llama_stack/providers/inline/tool_runtime/rag/__init__.py +1 -1
- llama_stack/providers/inline/tool_runtime/rag/config.py +8 -1
- llama_stack/providers/inline/tool_runtime/rag/context_retriever.py +7 -6
- llama_stack/providers/inline/tool_runtime/rag/memory.py +64 -48
- llama_stack/providers/inline/vector_io/chroma/__init__.py +1 -1
- llama_stack/providers/inline/vector_io/chroma/config.py +1 -1
- llama_stack/providers/inline/vector_io/faiss/__init__.py +1 -1
- llama_stack/providers/inline/vector_io/faiss/config.py +1 -1
- llama_stack/providers/inline/vector_io/faiss/faiss.py +43 -28
- llama_stack/providers/inline/vector_io/milvus/__init__.py +1 -1
- llama_stack/providers/inline/vector_io/milvus/config.py +1 -1
- llama_stack/providers/inline/vector_io/qdrant/__init__.py +1 -1
- llama_stack/providers/inline/vector_io/qdrant/config.py +1 -1
- llama_stack/providers/inline/vector_io/sqlite_vec/__init__.py +1 -1
- llama_stack/providers/inline/vector_io/sqlite_vec/sqlite_vec.py +40 -33
- llama_stack/providers/registry/agents.py +7 -3
- llama_stack/providers/registry/batches.py +1 -1
- llama_stack/providers/registry/datasetio.py +1 -1
- llama_stack/providers/registry/eval.py +1 -1
- llama_stack/{apis/datasets/__init__.py → providers/registry/file_processors.py} +5 -1
- llama_stack/providers/registry/files.py +11 -2
- llama_stack/providers/registry/inference.py +22 -3
- llama_stack/providers/registry/post_training.py +1 -1
- llama_stack/providers/registry/safety.py +1 -1
- llama_stack/providers/registry/scoring.py +1 -1
- llama_stack/providers/registry/tool_runtime.py +2 -2
- llama_stack/providers/registry/vector_io.py +7 -7
- llama_stack/providers/remote/datasetio/huggingface/huggingface.py +2 -5
- llama_stack/providers/remote/datasetio/nvidia/datasetio.py +1 -4
- llama_stack/providers/remote/eval/nvidia/eval.py +15 -9
- llama_stack/providers/remote/files/openai/__init__.py +19 -0
- llama_stack/providers/remote/files/openai/config.py +28 -0
- llama_stack/providers/remote/files/openai/files.py +253 -0
- llama_stack/providers/remote/files/s3/files.py +52 -30
- llama_stack/providers/remote/inference/anthropic/anthropic.py +2 -1
- llama_stack/providers/remote/inference/anthropic/config.py +1 -1
- llama_stack/providers/remote/inference/azure/azure.py +1 -3
- llama_stack/providers/remote/inference/azure/config.py +8 -7
- llama_stack/providers/remote/inference/bedrock/__init__.py +1 -1
- llama_stack/providers/remote/inference/bedrock/bedrock.py +82 -105
- llama_stack/providers/remote/inference/bedrock/config.py +24 -3
- llama_stack/providers/remote/inference/cerebras/cerebras.py +5 -5
- llama_stack/providers/remote/inference/cerebras/config.py +12 -5
- llama_stack/providers/remote/inference/databricks/config.py +13 -6
- llama_stack/providers/remote/inference/databricks/databricks.py +16 -6
- llama_stack/providers/remote/inference/fireworks/config.py +5 -5
- llama_stack/providers/remote/inference/fireworks/fireworks.py +1 -1
- llama_stack/providers/remote/inference/gemini/config.py +1 -1
- llama_stack/providers/remote/inference/gemini/gemini.py +13 -14
- llama_stack/providers/remote/inference/groq/config.py +5 -5
- llama_stack/providers/remote/inference/groq/groq.py +1 -1
- llama_stack/providers/remote/inference/llama_openai_compat/config.py +5 -5
- llama_stack/providers/remote/inference/llama_openai_compat/llama.py +8 -6
- llama_stack/providers/remote/inference/nvidia/__init__.py +1 -1
- llama_stack/providers/remote/inference/nvidia/config.py +21 -11
- llama_stack/providers/remote/inference/nvidia/nvidia.py +115 -3
- llama_stack/providers/remote/inference/nvidia/utils.py +1 -1
- llama_stack/providers/remote/inference/oci/__init__.py +17 -0
- llama_stack/providers/remote/inference/oci/auth.py +79 -0
- llama_stack/providers/remote/inference/oci/config.py +75 -0
- llama_stack/providers/remote/inference/oci/oci.py +162 -0
- llama_stack/providers/remote/inference/ollama/config.py +7 -5
- llama_stack/providers/remote/inference/ollama/ollama.py +17 -8
- llama_stack/providers/remote/inference/openai/config.py +4 -4
- llama_stack/providers/remote/inference/openai/openai.py +1 -1
- llama_stack/providers/remote/inference/passthrough/__init__.py +2 -2
- llama_stack/providers/remote/inference/passthrough/config.py +5 -10
- llama_stack/providers/remote/inference/passthrough/passthrough.py +97 -75
- llama_stack/providers/remote/inference/runpod/config.py +12 -5
- llama_stack/providers/remote/inference/runpod/runpod.py +2 -20
- llama_stack/providers/remote/inference/sambanova/config.py +5 -5
- llama_stack/providers/remote/inference/sambanova/sambanova.py +1 -1
- llama_stack/providers/remote/inference/tgi/config.py +7 -6
- llama_stack/providers/remote/inference/tgi/tgi.py +19 -11
- llama_stack/providers/remote/inference/together/config.py +5 -5
- llama_stack/providers/remote/inference/together/together.py +15 -12
- llama_stack/providers/remote/inference/vertexai/config.py +1 -1
- llama_stack/providers/remote/inference/vllm/config.py +5 -5
- llama_stack/providers/remote/inference/vllm/vllm.py +13 -14
- llama_stack/providers/remote/inference/watsonx/config.py +4 -4
- llama_stack/providers/remote/inference/watsonx/watsonx.py +21 -94
- llama_stack/providers/remote/post_training/nvidia/post_training.py +4 -4
- llama_stack/providers/remote/post_training/nvidia/utils.py +1 -1
- llama_stack/providers/remote/safety/bedrock/bedrock.py +6 -6
- llama_stack/providers/remote/safety/bedrock/config.py +1 -1
- llama_stack/providers/remote/safety/nvidia/config.py +1 -1
- llama_stack/providers/remote/safety/nvidia/nvidia.py +11 -5
- llama_stack/providers/remote/safety/sambanova/config.py +1 -1
- llama_stack/providers/remote/safety/sambanova/sambanova.py +6 -6
- llama_stack/providers/remote/tool_runtime/bing_search/bing_search.py +11 -6
- llama_stack/providers/remote/tool_runtime/brave_search/brave_search.py +12 -7
- llama_stack/providers/remote/tool_runtime/model_context_protocol/config.py +8 -2
- llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py +57 -15
- llama_stack/providers/remote/tool_runtime/tavily_search/tavily_search.py +11 -6
- llama_stack/providers/remote/tool_runtime/wolfram_alpha/wolfram_alpha.py +11 -6
- llama_stack/providers/remote/vector_io/chroma/__init__.py +1 -1
- llama_stack/providers/remote/vector_io/chroma/chroma.py +125 -20
- llama_stack/providers/remote/vector_io/chroma/config.py +1 -1
- llama_stack/providers/remote/vector_io/milvus/__init__.py +1 -1
- llama_stack/providers/remote/vector_io/milvus/config.py +1 -1
- llama_stack/providers/remote/vector_io/milvus/milvus.py +27 -21
- llama_stack/providers/remote/vector_io/pgvector/__init__.py +1 -1
- llama_stack/providers/remote/vector_io/pgvector/config.py +1 -1
- llama_stack/providers/remote/vector_io/pgvector/pgvector.py +26 -18
- llama_stack/providers/remote/vector_io/qdrant/__init__.py +1 -1
- llama_stack/providers/remote/vector_io/qdrant/config.py +1 -1
- llama_stack/providers/remote/vector_io/qdrant/qdrant.py +141 -24
- llama_stack/providers/remote/vector_io/weaviate/__init__.py +1 -1
- llama_stack/providers/remote/vector_io/weaviate/config.py +1 -1
- llama_stack/providers/remote/vector_io/weaviate/weaviate.py +26 -21
- llama_stack/providers/utils/common/data_schema_validator.py +1 -5
- llama_stack/providers/utils/files/form_data.py +1 -1
- llama_stack/providers/utils/inference/embedding_mixin.py +1 -1
- llama_stack/providers/utils/inference/inference_store.py +7 -8
- llama_stack/providers/utils/inference/litellm_openai_mixin.py +79 -79
- llama_stack/providers/utils/inference/model_registry.py +1 -3
- llama_stack/providers/utils/inference/openai_compat.py +44 -1171
- llama_stack/providers/utils/inference/openai_mixin.py +68 -42
- llama_stack/providers/utils/inference/prompt_adapter.py +50 -265
- llama_stack/providers/utils/inference/stream_utils.py +23 -0
- llama_stack/providers/utils/memory/__init__.py +2 -0
- llama_stack/providers/utils/memory/file_utils.py +1 -1
- llama_stack/providers/utils/memory/openai_vector_store_mixin.py +181 -84
- llama_stack/providers/utils/memory/vector_store.py +39 -38
- llama_stack/providers/utils/pagination.py +1 -1
- llama_stack/providers/utils/responses/responses_store.py +15 -25
- llama_stack/providers/utils/scoring/aggregation_utils.py +1 -2
- llama_stack/providers/utils/scoring/base_scoring_fn.py +1 -2
- llama_stack/providers/utils/tools/mcp.py +93 -11
- llama_stack/telemetry/constants.py +27 -0
- llama_stack/telemetry/helpers.py +43 -0
- llama_stack/testing/api_recorder.py +25 -16
- {llama_stack-0.3.5.dist-info → llama_stack-0.4.0.dist-info}/METADATA +56 -54
- llama_stack-0.4.0.dist-info/RECORD +588 -0
- llama_stack-0.4.0.dist-info/top_level.txt +2 -0
- llama_stack_api/__init__.py +945 -0
- llama_stack_api/admin/__init__.py +45 -0
- llama_stack_api/admin/api.py +72 -0
- llama_stack_api/admin/fastapi_routes.py +117 -0
- llama_stack_api/admin/models.py +113 -0
- llama_stack_api/agents.py +173 -0
- llama_stack_api/batches/__init__.py +40 -0
- llama_stack_api/batches/api.py +53 -0
- llama_stack_api/batches/fastapi_routes.py +113 -0
- llama_stack_api/batches/models.py +78 -0
- llama_stack_api/benchmarks/__init__.py +43 -0
- llama_stack_api/benchmarks/api.py +39 -0
- llama_stack_api/benchmarks/fastapi_routes.py +109 -0
- llama_stack_api/benchmarks/models.py +109 -0
- {llama_stack/apis → llama_stack_api}/common/content_types.py +1 -43
- {llama_stack/apis → llama_stack_api}/common/errors.py +0 -8
- {llama_stack/apis → llama_stack_api}/common/job_types.py +1 -1
- llama_stack_api/common/responses.py +77 -0
- {llama_stack/apis → llama_stack_api}/common/training_types.py +1 -1
- {llama_stack/apis → llama_stack_api}/common/type_system.py +2 -14
- llama_stack_api/connectors.py +146 -0
- {llama_stack/apis/conversations → llama_stack_api}/conversations.py +23 -39
- {llama_stack/apis/datasetio → llama_stack_api}/datasetio.py +4 -8
- llama_stack_api/datasets/__init__.py +61 -0
- llama_stack_api/datasets/api.py +35 -0
- llama_stack_api/datasets/fastapi_routes.py +104 -0
- llama_stack_api/datasets/models.py +152 -0
- {llama_stack/providers → llama_stack_api}/datatypes.py +166 -10
- {llama_stack/apis/eval → llama_stack_api}/eval.py +8 -40
- llama_stack_api/file_processors/__init__.py +27 -0
- llama_stack_api/file_processors/api.py +64 -0
- llama_stack_api/file_processors/fastapi_routes.py +78 -0
- llama_stack_api/file_processors/models.py +42 -0
- llama_stack_api/files/__init__.py +35 -0
- llama_stack_api/files/api.py +51 -0
- llama_stack_api/files/fastapi_routes.py +124 -0
- llama_stack_api/files/models.py +107 -0
- {llama_stack/apis/inference → llama_stack_api}/inference.py +90 -194
- llama_stack_api/inspect_api/__init__.py +37 -0
- llama_stack_api/inspect_api/api.py +25 -0
- llama_stack_api/inspect_api/fastapi_routes.py +76 -0
- llama_stack_api/inspect_api/models.py +28 -0
- {llama_stack/apis/agents → llama_stack_api/internal}/__init__.py +3 -1
- llama_stack/providers/utils/kvstore/api.py → llama_stack_api/internal/kvstore.py +5 -0
- llama_stack_api/internal/sqlstore.py +79 -0
- {llama_stack/apis/models → llama_stack_api}/models.py +11 -9
- {llama_stack/apis/agents → llama_stack_api}/openai_responses.py +184 -27
- {llama_stack/apis/post_training → llama_stack_api}/post_training.py +7 -11
- {llama_stack/apis/prompts → llama_stack_api}/prompts.py +3 -4
- llama_stack_api/providers/__init__.py +33 -0
- llama_stack_api/providers/api.py +16 -0
- llama_stack_api/providers/fastapi_routes.py +57 -0
- llama_stack_api/providers/models.py +24 -0
- {llama_stack/apis/tools → llama_stack_api}/rag_tool.py +2 -52
- {llama_stack/apis → llama_stack_api}/resource.py +1 -1
- llama_stack_api/router_utils.py +160 -0
- {llama_stack/apis/safety → llama_stack_api}/safety.py +6 -9
- {llama_stack → llama_stack_api}/schema_utils.py +94 -4
- {llama_stack/apis/scoring → llama_stack_api}/scoring.py +3 -3
- {llama_stack/apis/scoring_functions → llama_stack_api}/scoring_functions.py +9 -6
- {llama_stack/apis/shields → llama_stack_api}/shields.py +6 -7
- {llama_stack/apis/tools → llama_stack_api}/tools.py +26 -21
- {llama_stack/apis/vector_io → llama_stack_api}/vector_io.py +133 -152
- {llama_stack/apis/vector_stores → llama_stack_api}/vector_stores.py +1 -1
- llama_stack/apis/agents/agents.py +0 -894
- llama_stack/apis/batches/__init__.py +0 -9
- llama_stack/apis/batches/batches.py +0 -100
- llama_stack/apis/benchmarks/__init__.py +0 -7
- llama_stack/apis/benchmarks/benchmarks.py +0 -108
- llama_stack/apis/common/responses.py +0 -36
- llama_stack/apis/conversations/__init__.py +0 -31
- llama_stack/apis/datasets/datasets.py +0 -251
- llama_stack/apis/datatypes.py +0 -160
- llama_stack/apis/eval/__init__.py +0 -7
- llama_stack/apis/files/__init__.py +0 -7
- llama_stack/apis/files/files.py +0 -199
- llama_stack/apis/inference/__init__.py +0 -7
- llama_stack/apis/inference/event_logger.py +0 -43
- llama_stack/apis/inspect/__init__.py +0 -7
- llama_stack/apis/inspect/inspect.py +0 -94
- llama_stack/apis/models/__init__.py +0 -7
- llama_stack/apis/post_training/__init__.py +0 -7
- llama_stack/apis/prompts/__init__.py +0 -9
- llama_stack/apis/providers/__init__.py +0 -7
- llama_stack/apis/providers/providers.py +0 -69
- llama_stack/apis/safety/__init__.py +0 -7
- llama_stack/apis/scoring/__init__.py +0 -7
- llama_stack/apis/scoring_functions/__init__.py +0 -7
- llama_stack/apis/shields/__init__.py +0 -7
- llama_stack/apis/synthetic_data_generation/__init__.py +0 -7
- llama_stack/apis/synthetic_data_generation/synthetic_data_generation.py +0 -77
- llama_stack/apis/telemetry/__init__.py +0 -7
- llama_stack/apis/telemetry/telemetry.py +0 -423
- llama_stack/apis/tools/__init__.py +0 -8
- llama_stack/apis/vector_io/__init__.py +0 -7
- llama_stack/apis/vector_stores/__init__.py +0 -7
- llama_stack/core/server/tracing.py +0 -80
- llama_stack/core/ui/app.py +0 -55
- llama_stack/core/ui/modules/__init__.py +0 -5
- llama_stack/core/ui/modules/api.py +0 -32
- llama_stack/core/ui/modules/utils.py +0 -42
- llama_stack/core/ui/page/__init__.py +0 -5
- llama_stack/core/ui/page/distribution/__init__.py +0 -5
- llama_stack/core/ui/page/distribution/datasets.py +0 -18
- llama_stack/core/ui/page/distribution/eval_tasks.py +0 -20
- llama_stack/core/ui/page/distribution/models.py +0 -18
- llama_stack/core/ui/page/distribution/providers.py +0 -27
- llama_stack/core/ui/page/distribution/resources.py +0 -48
- llama_stack/core/ui/page/distribution/scoring_functions.py +0 -18
- llama_stack/core/ui/page/distribution/shields.py +0 -19
- llama_stack/core/ui/page/evaluations/__init__.py +0 -5
- llama_stack/core/ui/page/evaluations/app_eval.py +0 -143
- llama_stack/core/ui/page/evaluations/native_eval.py +0 -253
- llama_stack/core/ui/page/playground/__init__.py +0 -5
- llama_stack/core/ui/page/playground/chat.py +0 -130
- llama_stack/core/ui/page/playground/tools.py +0 -352
- llama_stack/distributions/dell/build.yaml +0 -33
- llama_stack/distributions/meta-reference-gpu/build.yaml +0 -32
- llama_stack/distributions/nvidia/build.yaml +0 -29
- llama_stack/distributions/open-benchmark/build.yaml +0 -36
- llama_stack/distributions/postgres-demo/__init__.py +0 -7
- llama_stack/distributions/postgres-demo/build.yaml +0 -23
- llama_stack/distributions/postgres-demo/postgres_demo.py +0 -125
- llama_stack/distributions/starter/build.yaml +0 -61
- llama_stack/distributions/starter-gpu/build.yaml +0 -61
- llama_stack/distributions/watsonx/build.yaml +0 -33
- llama_stack/providers/inline/agents/meta_reference/agent_instance.py +0 -1024
- llama_stack/providers/inline/agents/meta_reference/persistence.py +0 -228
- llama_stack/providers/inline/telemetry/__init__.py +0 -5
- llama_stack/providers/inline/telemetry/meta_reference/__init__.py +0 -21
- llama_stack/providers/inline/telemetry/meta_reference/config.py +0 -47
- llama_stack/providers/inline/telemetry/meta_reference/telemetry.py +0 -252
- llama_stack/providers/remote/inference/bedrock/models.py +0 -29
- llama_stack/providers/utils/kvstore/sqlite/config.py +0 -20
- llama_stack/providers/utils/sqlstore/__init__.py +0 -5
- llama_stack/providers/utils/sqlstore/api.py +0 -128
- llama_stack/providers/utils/telemetry/__init__.py +0 -5
- llama_stack/providers/utils/telemetry/trace_protocol.py +0 -142
- llama_stack/providers/utils/telemetry/tracing.py +0 -384
- llama_stack/strong_typing/__init__.py +0 -19
- llama_stack/strong_typing/auxiliary.py +0 -228
- llama_stack/strong_typing/classdef.py +0 -440
- llama_stack/strong_typing/core.py +0 -46
- llama_stack/strong_typing/deserializer.py +0 -877
- llama_stack/strong_typing/docstring.py +0 -409
- llama_stack/strong_typing/exception.py +0 -23
- llama_stack/strong_typing/inspection.py +0 -1085
- llama_stack/strong_typing/mapping.py +0 -40
- llama_stack/strong_typing/name.py +0 -182
- llama_stack/strong_typing/schema.py +0 -792
- llama_stack/strong_typing/serialization.py +0 -97
- llama_stack/strong_typing/serializer.py +0 -500
- llama_stack/strong_typing/slots.py +0 -27
- llama_stack/strong_typing/topological.py +0 -89
- llama_stack/ui/node_modules/flatted/python/flatted.py +0 -149
- llama_stack-0.3.5.dist-info/RECORD +0 -625
- llama_stack-0.3.5.dist-info/top_level.txt +0 -1
- /llama_stack/{providers/utils → core/storage}/kvstore/config.py +0 -0
- /llama_stack/{providers/utils → core/storage}/kvstore/mongodb/__init__.py +0 -0
- /llama_stack/{providers/utils → core/storage}/kvstore/postgres/__init__.py +0 -0
- /llama_stack/{providers/utils → core/storage}/kvstore/redis/__init__.py +0 -0
- /llama_stack/{providers/utils → core/storage}/kvstore/sqlite/__init__.py +0 -0
- /llama_stack/{apis → providers/inline/file_processor}/__init__.py +0 -0
- /llama_stack/{apis/common → telemetry}/__init__.py +0 -0
- {llama_stack-0.3.5.dist-info → llama_stack-0.4.0.dist-info}/WHEEL +0 -0
- {llama_stack-0.3.5.dist-info → llama_stack-0.4.0.dist-info}/entry_points.txt +0 -0
- {llama_stack-0.3.5.dist-info → llama_stack-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {llama_stack/core/ui → llama_stack_api/common}/__init__.py +0 -0
- {llama_stack/strong_typing → llama_stack_api}/py.typed +0 -0
- {llama_stack/apis → llama_stack_api}/version.py +0 -0
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
# All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# This source code is licensed under the terms described in the LICENSE file in
|
|
5
|
-
# the root directory of this source tree.
|
|
6
|
-
|
|
7
|
-
from collections.abc import Mapping, Sequence
|
|
8
|
-
from enum import Enum
|
|
9
|
-
from typing import Any, Literal, Protocol
|
|
10
|
-
|
|
11
|
-
from pydantic import BaseModel
|
|
12
|
-
|
|
13
|
-
from llama_stack.apis.common.responses import PaginatedResponse
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class ColumnType(Enum):
|
|
17
|
-
INTEGER = "INTEGER"
|
|
18
|
-
STRING = "STRING"
|
|
19
|
-
TEXT = "TEXT"
|
|
20
|
-
FLOAT = "FLOAT"
|
|
21
|
-
BOOLEAN = "BOOLEAN"
|
|
22
|
-
JSON = "JSON"
|
|
23
|
-
DATETIME = "DATETIME"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class ColumnDefinition(BaseModel):
|
|
27
|
-
type: ColumnType
|
|
28
|
-
primary_key: bool = False
|
|
29
|
-
nullable: bool = True
|
|
30
|
-
default: Any = None
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class SqlStore(Protocol):
|
|
34
|
-
"""
|
|
35
|
-
A protocol for a SQL store.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
async def create_table(self, table: str, schema: Mapping[str, ColumnType | ColumnDefinition]) -> None:
|
|
39
|
-
"""
|
|
40
|
-
Create a table.
|
|
41
|
-
"""
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
async def insert(self, table: str, data: Mapping[str, Any] | Sequence[Mapping[str, Any]]) -> None:
|
|
45
|
-
"""
|
|
46
|
-
Insert a row or batch of rows into a table.
|
|
47
|
-
"""
|
|
48
|
-
pass
|
|
49
|
-
|
|
50
|
-
async def fetch_all(
|
|
51
|
-
self,
|
|
52
|
-
table: str,
|
|
53
|
-
where: Mapping[str, Any] | None = None,
|
|
54
|
-
where_sql: str | None = None,
|
|
55
|
-
limit: int | None = None,
|
|
56
|
-
order_by: list[tuple[str, Literal["asc", "desc"]]] | None = None,
|
|
57
|
-
cursor: tuple[str, str] | None = None,
|
|
58
|
-
) -> PaginatedResponse:
|
|
59
|
-
"""
|
|
60
|
-
Fetch all rows from a table with optional cursor-based pagination.
|
|
61
|
-
|
|
62
|
-
:param table: The table name
|
|
63
|
-
:param where: Simple key-value WHERE conditions
|
|
64
|
-
:param where_sql: Raw SQL WHERE clause for complex queries
|
|
65
|
-
:param limit: Maximum number of records to return
|
|
66
|
-
:param order_by: List of (column, order) tuples for sorting
|
|
67
|
-
:param cursor: Tuple of (key_column, cursor_id) for pagination (None for first page)
|
|
68
|
-
Requires order_by with exactly one column when used
|
|
69
|
-
:return: PaginatedResult with data and has_more flag
|
|
70
|
-
|
|
71
|
-
Note: Cursor pagination only supports single-column ordering for simplicity.
|
|
72
|
-
Multi-column ordering is allowed without cursor but will raise an error with cursor.
|
|
73
|
-
"""
|
|
74
|
-
pass
|
|
75
|
-
|
|
76
|
-
async def fetch_one(
|
|
77
|
-
self,
|
|
78
|
-
table: str,
|
|
79
|
-
where: Mapping[str, Any] | None = None,
|
|
80
|
-
where_sql: str | None = None,
|
|
81
|
-
order_by: list[tuple[str, Literal["asc", "desc"]]] | None = None,
|
|
82
|
-
) -> dict[str, Any] | None:
|
|
83
|
-
"""
|
|
84
|
-
Fetch one row from a table.
|
|
85
|
-
"""
|
|
86
|
-
pass
|
|
87
|
-
|
|
88
|
-
async def update(
|
|
89
|
-
self,
|
|
90
|
-
table: str,
|
|
91
|
-
data: Mapping[str, Any],
|
|
92
|
-
where: Mapping[str, Any],
|
|
93
|
-
) -> None:
|
|
94
|
-
"""
|
|
95
|
-
Update a row in a table.
|
|
96
|
-
"""
|
|
97
|
-
pass
|
|
98
|
-
|
|
99
|
-
async def delete(
|
|
100
|
-
self,
|
|
101
|
-
table: str,
|
|
102
|
-
where: Mapping[str, Any],
|
|
103
|
-
) -> None:
|
|
104
|
-
"""
|
|
105
|
-
Delete a row from a table.
|
|
106
|
-
"""
|
|
107
|
-
pass
|
|
108
|
-
|
|
109
|
-
async def add_column_if_not_exists(
|
|
110
|
-
self,
|
|
111
|
-
table: str,
|
|
112
|
-
column_name: str,
|
|
113
|
-
column_type: ColumnType,
|
|
114
|
-
nullable: bool = True,
|
|
115
|
-
) -> None:
|
|
116
|
-
"""
|
|
117
|
-
Add a column to an existing table if the column doesn't already exist.
|
|
118
|
-
|
|
119
|
-
This is useful for table migrations when adding new functionality.
|
|
120
|
-
If the table doesn't exist, this method should do nothing.
|
|
121
|
-
If the column already exists, this method should do nothing.
|
|
122
|
-
|
|
123
|
-
:param table: Table name
|
|
124
|
-
:param column_name: Name of the column to add
|
|
125
|
-
:param column_type: Type of the column to add
|
|
126
|
-
:param nullable: Whether the column should be nullable (default: True)
|
|
127
|
-
"""
|
|
128
|
-
pass
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
# All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# This source code is licensed under the terms described in the LICENSE file in
|
|
5
|
-
# the root directory of this source tree.
|
|
6
|
-
|
|
7
|
-
import asyncio
|
|
8
|
-
import inspect
|
|
9
|
-
import json
|
|
10
|
-
from collections.abc import AsyncGenerator, Callable
|
|
11
|
-
from functools import wraps
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
from pydantic import BaseModel
|
|
15
|
-
|
|
16
|
-
from llama_stack.models.llama.datatypes import Primitive
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def serialize_value(value: Any) -> Primitive:
|
|
20
|
-
return str(_prepare_for_json(value))
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def _prepare_for_json(value: Any) -> str:
|
|
24
|
-
"""Serialize a single value into JSON-compatible format."""
|
|
25
|
-
if value is None:
|
|
26
|
-
return ""
|
|
27
|
-
elif isinstance(value, str | int | float | bool):
|
|
28
|
-
return value
|
|
29
|
-
elif hasattr(value, "_name_"):
|
|
30
|
-
return value._name_
|
|
31
|
-
elif isinstance(value, BaseModel):
|
|
32
|
-
return json.loads(value.model_dump_json())
|
|
33
|
-
elif isinstance(value, list | tuple | set):
|
|
34
|
-
return [_prepare_for_json(item) for item in value]
|
|
35
|
-
elif isinstance(value, dict):
|
|
36
|
-
return {str(k): _prepare_for_json(v) for k, v in value.items()}
|
|
37
|
-
else:
|
|
38
|
-
try:
|
|
39
|
-
json.dumps(value)
|
|
40
|
-
return value
|
|
41
|
-
except Exception:
|
|
42
|
-
return str(value)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def trace_protocol[T](cls: type[T]) -> type[T]:
|
|
46
|
-
"""
|
|
47
|
-
A class decorator that automatically traces all methods in a protocol/base class
|
|
48
|
-
and its inheriting classes.
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
def trace_method(method: Callable) -> Callable:
|
|
52
|
-
is_async = asyncio.iscoroutinefunction(method)
|
|
53
|
-
is_async_gen = inspect.isasyncgenfunction(method)
|
|
54
|
-
|
|
55
|
-
def create_span_context(self: Any, *args: Any, **kwargs: Any) -> tuple:
|
|
56
|
-
class_name = self.__class__.__name__
|
|
57
|
-
method_name = method.__name__
|
|
58
|
-
span_type = "async_generator" if is_async_gen else "async" if is_async else "sync"
|
|
59
|
-
sig = inspect.signature(method)
|
|
60
|
-
param_names = list(sig.parameters.keys())[1:] # Skip 'self'
|
|
61
|
-
combined_args = {}
|
|
62
|
-
for i, arg in enumerate(args):
|
|
63
|
-
param_name = param_names[i] if i < len(param_names) else f"position_{i + 1}"
|
|
64
|
-
combined_args[param_name] = serialize_value(arg)
|
|
65
|
-
for k, v in kwargs.items():
|
|
66
|
-
combined_args[str(k)] = serialize_value(v)
|
|
67
|
-
|
|
68
|
-
span_attributes = {
|
|
69
|
-
"__autotraced__": True,
|
|
70
|
-
"__class__": class_name,
|
|
71
|
-
"__method__": method_name,
|
|
72
|
-
"__type__": span_type,
|
|
73
|
-
"__args__": json.dumps(combined_args),
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return class_name, method_name, span_attributes
|
|
77
|
-
|
|
78
|
-
@wraps(method)
|
|
79
|
-
async def async_gen_wrapper(self: Any, *args: Any, **kwargs: Any) -> AsyncGenerator:
|
|
80
|
-
from llama_stack.providers.utils.telemetry import tracing
|
|
81
|
-
|
|
82
|
-
class_name, method_name, span_attributes = create_span_context(self, *args, **kwargs)
|
|
83
|
-
|
|
84
|
-
with tracing.span(f"{class_name}.{method_name}", span_attributes) as span:
|
|
85
|
-
count = 0
|
|
86
|
-
try:
|
|
87
|
-
async for item in method(self, *args, **kwargs):
|
|
88
|
-
yield item
|
|
89
|
-
count += 1
|
|
90
|
-
finally:
|
|
91
|
-
span.set_attribute("chunk_count", count)
|
|
92
|
-
|
|
93
|
-
@wraps(method)
|
|
94
|
-
async def async_wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
95
|
-
from llama_stack.providers.utils.telemetry import tracing
|
|
96
|
-
|
|
97
|
-
class_name, method_name, span_attributes = create_span_context(self, *args, **kwargs)
|
|
98
|
-
|
|
99
|
-
with tracing.span(f"{class_name}.{method_name}", span_attributes) as span:
|
|
100
|
-
try:
|
|
101
|
-
result = await method(self, *args, **kwargs)
|
|
102
|
-
span.set_attribute("output", serialize_value(result))
|
|
103
|
-
return result
|
|
104
|
-
except Exception as e:
|
|
105
|
-
span.set_attribute("error", str(e))
|
|
106
|
-
raise
|
|
107
|
-
|
|
108
|
-
@wraps(method)
|
|
109
|
-
def sync_wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
110
|
-
from llama_stack.providers.utils.telemetry import tracing
|
|
111
|
-
|
|
112
|
-
class_name, method_name, span_attributes = create_span_context(self, *args, **kwargs)
|
|
113
|
-
|
|
114
|
-
with tracing.span(f"{class_name}.{method_name}", span_attributes) as span:
|
|
115
|
-
try:
|
|
116
|
-
result = method(self, *args, **kwargs)
|
|
117
|
-
span.set_attribute("output", serialize_value(result))
|
|
118
|
-
return result
|
|
119
|
-
except Exception as e:
|
|
120
|
-
span.set_attribute("error", str(e))
|
|
121
|
-
raise
|
|
122
|
-
|
|
123
|
-
if is_async_gen:
|
|
124
|
-
return async_gen_wrapper
|
|
125
|
-
elif is_async:
|
|
126
|
-
return async_wrapper
|
|
127
|
-
else:
|
|
128
|
-
return sync_wrapper
|
|
129
|
-
|
|
130
|
-
original_init_subclass = getattr(cls, "__init_subclass__", None)
|
|
131
|
-
|
|
132
|
-
def __init_subclass__(cls_child, **kwargs): # noqa: N807
|
|
133
|
-
if original_init_subclass:
|
|
134
|
-
original_init_subclass(**kwargs)
|
|
135
|
-
|
|
136
|
-
for name, method in vars(cls_child).items():
|
|
137
|
-
if inspect.isfunction(method) and not name.startswith("_"):
|
|
138
|
-
setattr(cls_child, name, trace_method(method)) # noqa: B010
|
|
139
|
-
|
|
140
|
-
cls.__init_subclass__ = classmethod(__init_subclass__)
|
|
141
|
-
|
|
142
|
-
return cls
|
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
# All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# This source code is licensed under the terms described in the LICENSE file in
|
|
5
|
-
# the root directory of this source tree.
|
|
6
|
-
|
|
7
|
-
import asyncio
|
|
8
|
-
import contextvars
|
|
9
|
-
import logging # allow-direct-logging
|
|
10
|
-
import queue
|
|
11
|
-
import secrets
|
|
12
|
-
import sys
|
|
13
|
-
import threading
|
|
14
|
-
import time
|
|
15
|
-
from collections.abc import Callable
|
|
16
|
-
from datetime import UTC, datetime
|
|
17
|
-
from functools import wraps
|
|
18
|
-
from typing import Any
|
|
19
|
-
|
|
20
|
-
from llama_stack.apis.telemetry import (
|
|
21
|
-
Event,
|
|
22
|
-
LogSeverity,
|
|
23
|
-
Span,
|
|
24
|
-
SpanEndPayload,
|
|
25
|
-
SpanStartPayload,
|
|
26
|
-
SpanStatus,
|
|
27
|
-
StructuredLogEvent,
|
|
28
|
-
Telemetry,
|
|
29
|
-
UnstructuredLogEvent,
|
|
30
|
-
)
|
|
31
|
-
from llama_stack.log import get_logger
|
|
32
|
-
from llama_stack.providers.utils.telemetry.trace_protocol import serialize_value
|
|
33
|
-
|
|
34
|
-
logger = get_logger(__name__, category="core")
|
|
35
|
-
|
|
36
|
-
# Fallback logger that does NOT propagate to TelemetryHandler to avoid recursion
|
|
37
|
-
_fallback_logger = logging.getLogger("llama_stack.telemetry.background")
|
|
38
|
-
if not _fallback_logger.handlers:
|
|
39
|
-
_fallback_logger.propagate = False
|
|
40
|
-
_fallback_logger.setLevel(logging.ERROR)
|
|
41
|
-
_fallback_handler = logging.StreamHandler(sys.stderr)
|
|
42
|
-
_fallback_handler.setLevel(logging.ERROR)
|
|
43
|
-
_fallback_handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s"))
|
|
44
|
-
_fallback_logger.addHandler(_fallback_handler)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
INVALID_SPAN_ID = 0x0000000000000000
|
|
48
|
-
INVALID_TRACE_ID = 0x00000000000000000000000000000000
|
|
49
|
-
|
|
50
|
-
ROOT_SPAN_MARKERS = ["__root__", "__root_span__"]
|
|
51
|
-
# The logical root span may not be visible to this process if a parent context
|
|
52
|
-
# is passed in. The local root span is the first local span in a trace.
|
|
53
|
-
LOCAL_ROOT_SPAN_MARKER = "__local_root_span__"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def trace_id_to_str(trace_id: int) -> str:
|
|
57
|
-
"""Convenience trace ID formatting method
|
|
58
|
-
Args:
|
|
59
|
-
trace_id: Trace ID int
|
|
60
|
-
|
|
61
|
-
Returns:
|
|
62
|
-
The trace ID as 32-byte hexadecimal string
|
|
63
|
-
"""
|
|
64
|
-
return format(trace_id, "032x")
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def span_id_to_str(span_id: int) -> str:
|
|
68
|
-
"""Convenience span ID formatting method
|
|
69
|
-
Args:
|
|
70
|
-
span_id: Span ID int
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
The span ID as 16-byte hexadecimal string
|
|
74
|
-
"""
|
|
75
|
-
return format(span_id, "016x")
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def generate_span_id() -> str:
|
|
79
|
-
span_id = secrets.randbits(64)
|
|
80
|
-
while span_id == INVALID_SPAN_ID:
|
|
81
|
-
span_id = secrets.randbits(64)
|
|
82
|
-
return span_id_to_str(span_id)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def generate_trace_id() -> str:
|
|
86
|
-
trace_id = secrets.randbits(128)
|
|
87
|
-
while trace_id == INVALID_TRACE_ID:
|
|
88
|
-
trace_id = secrets.randbits(128)
|
|
89
|
-
return trace_id_to_str(trace_id)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
CURRENT_TRACE_CONTEXT = contextvars.ContextVar("trace_context", default=None)
|
|
93
|
-
BACKGROUND_LOGGER = None
|
|
94
|
-
|
|
95
|
-
LOG_QUEUE_FULL_LOG_INTERVAL_SECONDS = 60.0
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class BackgroundLogger:
|
|
99
|
-
def __init__(self, api: Telemetry, capacity: int = 100000):
|
|
100
|
-
self.api = api
|
|
101
|
-
self.log_queue: queue.Queue[Any] = queue.Queue(maxsize=capacity)
|
|
102
|
-
self.worker_thread = threading.Thread(target=self._worker, daemon=True)
|
|
103
|
-
self.worker_thread.start()
|
|
104
|
-
self._last_queue_full_log_time: float = 0.0
|
|
105
|
-
self._dropped_since_last_notice: int = 0
|
|
106
|
-
|
|
107
|
-
def log_event(self, event):
|
|
108
|
-
try:
|
|
109
|
-
self.log_queue.put_nowait(event)
|
|
110
|
-
except queue.Full:
|
|
111
|
-
# Aggregate drops and emit at most once per interval via fallback logger
|
|
112
|
-
self._dropped_since_last_notice += 1
|
|
113
|
-
current_time = time.time()
|
|
114
|
-
if current_time - self._last_queue_full_log_time >= LOG_QUEUE_FULL_LOG_INTERVAL_SECONDS:
|
|
115
|
-
_fallback_logger.error(
|
|
116
|
-
"Log queue is full; dropped %d events since last notice",
|
|
117
|
-
self._dropped_since_last_notice,
|
|
118
|
-
)
|
|
119
|
-
self._last_queue_full_log_time = current_time
|
|
120
|
-
self._dropped_since_last_notice = 0
|
|
121
|
-
|
|
122
|
-
def _worker(self):
|
|
123
|
-
loop = asyncio.new_event_loop()
|
|
124
|
-
asyncio.set_event_loop(loop)
|
|
125
|
-
loop.run_until_complete(self._process_logs())
|
|
126
|
-
|
|
127
|
-
async def _process_logs(self):
|
|
128
|
-
while True:
|
|
129
|
-
try:
|
|
130
|
-
event = self.log_queue.get()
|
|
131
|
-
await self.api.log_event(event)
|
|
132
|
-
except Exception:
|
|
133
|
-
import traceback
|
|
134
|
-
|
|
135
|
-
traceback.print_exc()
|
|
136
|
-
print("Error processing log event")
|
|
137
|
-
finally:
|
|
138
|
-
self.log_queue.task_done()
|
|
139
|
-
|
|
140
|
-
def __del__(self):
|
|
141
|
-
self.log_queue.join()
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def enqueue_event(event: Event) -> None:
|
|
145
|
-
"""Enqueue a telemetry event to the background logger if available.
|
|
146
|
-
|
|
147
|
-
This provides a non-blocking path for routers and other hot paths to
|
|
148
|
-
submit telemetry without awaiting the Telemetry API, reducing contention
|
|
149
|
-
with the main event loop.
|
|
150
|
-
"""
|
|
151
|
-
global BACKGROUND_LOGGER
|
|
152
|
-
if BACKGROUND_LOGGER is None:
|
|
153
|
-
raise RuntimeError("Telemetry API not initialized")
|
|
154
|
-
BACKGROUND_LOGGER.log_event(event)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
class TraceContext:
|
|
158
|
-
spans: list[Span] = []
|
|
159
|
-
|
|
160
|
-
def __init__(self, logger: BackgroundLogger, trace_id: str):
|
|
161
|
-
self.logger = logger
|
|
162
|
-
self.trace_id = trace_id
|
|
163
|
-
|
|
164
|
-
def push_span(self, name: str, attributes: dict[str, Any] = None) -> Span:
|
|
165
|
-
current_span = self.get_current_span()
|
|
166
|
-
span = Span(
|
|
167
|
-
span_id=generate_span_id(),
|
|
168
|
-
trace_id=self.trace_id,
|
|
169
|
-
name=name,
|
|
170
|
-
start_time=datetime.now(UTC),
|
|
171
|
-
parent_span_id=current_span.span_id if current_span else None,
|
|
172
|
-
attributes=attributes,
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
self.logger.log_event(
|
|
176
|
-
StructuredLogEvent(
|
|
177
|
-
trace_id=span.trace_id,
|
|
178
|
-
span_id=span.span_id,
|
|
179
|
-
timestamp=span.start_time,
|
|
180
|
-
attributes=span.attributes,
|
|
181
|
-
payload=SpanStartPayload(
|
|
182
|
-
name=span.name,
|
|
183
|
-
parent_span_id=span.parent_span_id,
|
|
184
|
-
),
|
|
185
|
-
)
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
self.spans.append(span)
|
|
189
|
-
return span
|
|
190
|
-
|
|
191
|
-
def pop_span(self, status: SpanStatus = SpanStatus.OK):
|
|
192
|
-
span = self.spans.pop()
|
|
193
|
-
if span is not None:
|
|
194
|
-
self.logger.log_event(
|
|
195
|
-
StructuredLogEvent(
|
|
196
|
-
trace_id=span.trace_id,
|
|
197
|
-
span_id=span.span_id,
|
|
198
|
-
timestamp=span.start_time,
|
|
199
|
-
attributes=span.attributes,
|
|
200
|
-
payload=SpanEndPayload(
|
|
201
|
-
status=status,
|
|
202
|
-
),
|
|
203
|
-
)
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
def get_current_span(self):
|
|
207
|
-
return self.spans[-1] if self.spans else None
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
def setup_logger(api: Telemetry, level: int = logging.INFO):
|
|
211
|
-
global BACKGROUND_LOGGER
|
|
212
|
-
|
|
213
|
-
if BACKGROUND_LOGGER is None:
|
|
214
|
-
BACKGROUND_LOGGER = BackgroundLogger(api)
|
|
215
|
-
root_logger = logging.getLogger()
|
|
216
|
-
root_logger.setLevel(level)
|
|
217
|
-
root_logger.addHandler(TelemetryHandler())
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
async def start_trace(name: str, attributes: dict[str, Any] = None) -> TraceContext:
|
|
221
|
-
global CURRENT_TRACE_CONTEXT, BACKGROUND_LOGGER
|
|
222
|
-
|
|
223
|
-
if BACKGROUND_LOGGER is None:
|
|
224
|
-
logger.debug("No Telemetry implementation set. Skipping trace initialization...")
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
trace_id = generate_trace_id()
|
|
228
|
-
context = TraceContext(BACKGROUND_LOGGER, trace_id)
|
|
229
|
-
# Mark this span as the root for the trace for now. The processing of
|
|
230
|
-
# traceparent context if supplied comes later and will result in the
|
|
231
|
-
# ROOT_SPAN_MARKERS being removed. Also mark this is the 'local' root,
|
|
232
|
-
# i.e. the root of the spans originating in this process as this is
|
|
233
|
-
# needed to ensure that we insert this 'local' root span's id into
|
|
234
|
-
# the trace record in sqlite store.
|
|
235
|
-
attributes = dict.fromkeys(ROOT_SPAN_MARKERS, True) | {LOCAL_ROOT_SPAN_MARKER: True} | (attributes or {})
|
|
236
|
-
context.push_span(name, attributes)
|
|
237
|
-
|
|
238
|
-
CURRENT_TRACE_CONTEXT.set(context)
|
|
239
|
-
return context
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
async def end_trace(status: SpanStatus = SpanStatus.OK):
|
|
243
|
-
global CURRENT_TRACE_CONTEXT
|
|
244
|
-
|
|
245
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
246
|
-
if context is None:
|
|
247
|
-
logger.debug("No trace context to end")
|
|
248
|
-
return
|
|
249
|
-
|
|
250
|
-
context.pop_span(status)
|
|
251
|
-
CURRENT_TRACE_CONTEXT.set(None)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def severity(levelname: str) -> LogSeverity:
|
|
255
|
-
if levelname == "DEBUG":
|
|
256
|
-
return LogSeverity.DEBUG
|
|
257
|
-
elif levelname == "INFO":
|
|
258
|
-
return LogSeverity.INFO
|
|
259
|
-
elif levelname == "WARNING":
|
|
260
|
-
return LogSeverity.WARN
|
|
261
|
-
elif levelname == "ERROR":
|
|
262
|
-
return LogSeverity.ERROR
|
|
263
|
-
elif levelname == "CRITICAL":
|
|
264
|
-
return LogSeverity.CRITICAL
|
|
265
|
-
else:
|
|
266
|
-
raise ValueError(f"Unknown log level: {levelname}")
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
# TODO: ideally, the actual emitting should be done inside a separate daemon
|
|
270
|
-
# process completely isolated from the server
|
|
271
|
-
class TelemetryHandler(logging.Handler):
|
|
272
|
-
def emit(self, record: logging.LogRecord):
|
|
273
|
-
# horrendous hack to avoid logging from asyncio and getting into an infinite loop
|
|
274
|
-
if record.module in ("asyncio", "selector_events"):
|
|
275
|
-
return
|
|
276
|
-
|
|
277
|
-
global CURRENT_TRACE_CONTEXT
|
|
278
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
279
|
-
if context is None:
|
|
280
|
-
return
|
|
281
|
-
|
|
282
|
-
span = context.get_current_span()
|
|
283
|
-
if span is None:
|
|
284
|
-
return
|
|
285
|
-
|
|
286
|
-
enqueue_event(
|
|
287
|
-
UnstructuredLogEvent(
|
|
288
|
-
trace_id=span.trace_id,
|
|
289
|
-
span_id=span.span_id,
|
|
290
|
-
timestamp=datetime.now(UTC),
|
|
291
|
-
message=self.format(record),
|
|
292
|
-
severity=severity(record.levelname),
|
|
293
|
-
)
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
def close(self):
|
|
297
|
-
pass
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
class SpanContextManager:
|
|
301
|
-
def __init__(self, name: str, attributes: dict[str, Any] = None):
|
|
302
|
-
self.name = name
|
|
303
|
-
self.attributes = attributes
|
|
304
|
-
self.span = None
|
|
305
|
-
|
|
306
|
-
def __enter__(self):
|
|
307
|
-
global CURRENT_TRACE_CONTEXT
|
|
308
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
309
|
-
if not context:
|
|
310
|
-
logger.debug("No trace context to push span")
|
|
311
|
-
return self
|
|
312
|
-
|
|
313
|
-
self.span = context.push_span(self.name, self.attributes)
|
|
314
|
-
return self
|
|
315
|
-
|
|
316
|
-
def __exit__(self, exc_type, exc_value, traceback):
|
|
317
|
-
global CURRENT_TRACE_CONTEXT
|
|
318
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
319
|
-
if not context:
|
|
320
|
-
logger.debug("No trace context to pop span")
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
context.pop_span()
|
|
324
|
-
|
|
325
|
-
def set_attribute(self, key: str, value: Any):
|
|
326
|
-
if self.span:
|
|
327
|
-
if self.span.attributes is None:
|
|
328
|
-
self.span.attributes = {}
|
|
329
|
-
self.span.attributes[key] = serialize_value(value)
|
|
330
|
-
|
|
331
|
-
async def __aenter__(self):
|
|
332
|
-
global CURRENT_TRACE_CONTEXT
|
|
333
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
334
|
-
if not context:
|
|
335
|
-
logger.debug("No trace context to push span")
|
|
336
|
-
return self
|
|
337
|
-
|
|
338
|
-
self.span = context.push_span(self.name, self.attributes)
|
|
339
|
-
return self
|
|
340
|
-
|
|
341
|
-
async def __aexit__(self, exc_type, exc_value, traceback):
|
|
342
|
-
global CURRENT_TRACE_CONTEXT
|
|
343
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
344
|
-
if not context:
|
|
345
|
-
logger.debug("No trace context to pop span")
|
|
346
|
-
return
|
|
347
|
-
|
|
348
|
-
context.pop_span()
|
|
349
|
-
|
|
350
|
-
def __call__(self, func: Callable):
|
|
351
|
-
@wraps(func)
|
|
352
|
-
def sync_wrapper(*args, **kwargs):
|
|
353
|
-
with self:
|
|
354
|
-
return func(*args, **kwargs)
|
|
355
|
-
|
|
356
|
-
@wraps(func)
|
|
357
|
-
async def async_wrapper(*args, **kwargs):
|
|
358
|
-
async with self:
|
|
359
|
-
return await func(*args, **kwargs)
|
|
360
|
-
|
|
361
|
-
@wraps(func)
|
|
362
|
-
def wrapper(*args, **kwargs):
|
|
363
|
-
if asyncio.iscoroutinefunction(func):
|
|
364
|
-
return async_wrapper(*args, **kwargs)
|
|
365
|
-
else:
|
|
366
|
-
return sync_wrapper(*args, **kwargs)
|
|
367
|
-
|
|
368
|
-
return wrapper
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
def span(name: str, attributes: dict[str, Any] = None):
|
|
372
|
-
return SpanContextManager(name, attributes)
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
def get_current_span() -> Span | None:
|
|
376
|
-
global CURRENT_TRACE_CONTEXT
|
|
377
|
-
if CURRENT_TRACE_CONTEXT is None:
|
|
378
|
-
logger.debug("No trace context to get current span")
|
|
379
|
-
return None
|
|
380
|
-
|
|
381
|
-
context = CURRENT_TRACE_CONTEXT.get()
|
|
382
|
-
if context:
|
|
383
|
-
return context.get_current_span()
|
|
384
|
-
return None
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
# All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# This source code is licensed under the terms described in the LICENSE file in
|
|
5
|
-
# the root directory of this source tree.
|
|
6
|
-
|
|
7
|
-
"""
|
|
8
|
-
Type-safe data interchange for Python data classes.
|
|
9
|
-
|
|
10
|
-
Provides auxiliary services for working with Python type annotations, converting typed data to and from JSON,
|
|
11
|
-
and generating a JSON schema for a complex type.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
__version__ = "0.3.4"
|
|
15
|
-
__author__ = "Levente Hunyadi"
|
|
16
|
-
__copyright__ = "Copyright 2021-2024, Levente Hunyadi"
|
|
17
|
-
__license__ = "MIT"
|
|
18
|
-
__maintainer__ = "Levente Hunyadi"
|
|
19
|
-
__status__ = "Production"
|