llama-stack 0.3.4__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.
Files changed (458) hide show
  1. llama_stack/__init__.py +0 -5
  2. llama_stack/cli/llama.py +3 -3
  3. llama_stack/cli/stack/_list_deps.py +12 -23
  4. llama_stack/cli/stack/list_stacks.py +37 -18
  5. llama_stack/cli/stack/run.py +121 -11
  6. llama_stack/cli/stack/utils.py +0 -127
  7. llama_stack/core/access_control/access_control.py +69 -28
  8. llama_stack/core/access_control/conditions.py +15 -5
  9. llama_stack/core/admin.py +267 -0
  10. llama_stack/core/build.py +6 -74
  11. llama_stack/core/client.py +1 -1
  12. llama_stack/core/configure.py +6 -6
  13. llama_stack/core/conversations/conversations.py +28 -25
  14. llama_stack/core/datatypes.py +271 -79
  15. llama_stack/core/distribution.py +15 -16
  16. llama_stack/core/external.py +3 -3
  17. llama_stack/core/inspect.py +98 -15
  18. llama_stack/core/library_client.py +73 -61
  19. llama_stack/core/prompts/prompts.py +12 -11
  20. llama_stack/core/providers.py +17 -11
  21. llama_stack/core/resolver.py +65 -56
  22. llama_stack/core/routers/__init__.py +8 -12
  23. llama_stack/core/routers/datasets.py +1 -4
  24. llama_stack/core/routers/eval_scoring.py +7 -4
  25. llama_stack/core/routers/inference.py +55 -271
  26. llama_stack/core/routers/safety.py +52 -24
  27. llama_stack/core/routers/tool_runtime.py +6 -48
  28. llama_stack/core/routers/vector_io.py +130 -51
  29. llama_stack/core/routing_tables/benchmarks.py +24 -20
  30. llama_stack/core/routing_tables/common.py +1 -4
  31. llama_stack/core/routing_tables/datasets.py +22 -22
  32. llama_stack/core/routing_tables/models.py +119 -6
  33. llama_stack/core/routing_tables/scoring_functions.py +7 -7
  34. llama_stack/core/routing_tables/shields.py +1 -2
  35. llama_stack/core/routing_tables/toolgroups.py +17 -7
  36. llama_stack/core/routing_tables/vector_stores.py +51 -16
  37. llama_stack/core/server/auth.py +5 -3
  38. llama_stack/core/server/auth_providers.py +36 -20
  39. llama_stack/core/server/fastapi_router_registry.py +84 -0
  40. llama_stack/core/server/quota.py +2 -2
  41. llama_stack/core/server/routes.py +79 -27
  42. llama_stack/core/server/server.py +102 -87
  43. llama_stack/core/stack.py +201 -58
  44. llama_stack/core/storage/datatypes.py +26 -3
  45. llama_stack/{providers/utils → core/storage}/kvstore/__init__.py +2 -0
  46. llama_stack/{providers/utils → core/storage}/kvstore/kvstore.py +55 -24
  47. llama_stack/{providers/utils → core/storage}/kvstore/mongodb/mongodb.py +13 -10
  48. llama_stack/{providers/utils → core/storage}/kvstore/postgres/postgres.py +28 -17
  49. llama_stack/{providers/utils → core/storage}/kvstore/redis/redis.py +41 -16
  50. llama_stack/{providers/utils → core/storage}/kvstore/sqlite/sqlite.py +1 -1
  51. llama_stack/core/storage/sqlstore/__init__.py +17 -0
  52. llama_stack/{providers/utils → core/storage}/sqlstore/authorized_sqlstore.py +69 -49
  53. llama_stack/{providers/utils → core/storage}/sqlstore/sqlalchemy_sqlstore.py +47 -17
  54. llama_stack/{providers/utils → core/storage}/sqlstore/sqlstore.py +25 -8
  55. llama_stack/core/store/registry.py +1 -1
  56. llama_stack/core/utils/config.py +8 -2
  57. llama_stack/core/utils/config_resolution.py +32 -29
  58. llama_stack/core/utils/context.py +4 -10
  59. llama_stack/core/utils/exec.py +9 -0
  60. llama_stack/core/utils/type_inspection.py +45 -0
  61. llama_stack/distributions/dell/{run.yaml → config.yaml} +3 -2
  62. llama_stack/distributions/dell/dell.py +2 -2
  63. llama_stack/distributions/dell/run-with-safety.yaml +3 -2
  64. llama_stack/distributions/meta-reference-gpu/{run.yaml → config.yaml} +3 -2
  65. llama_stack/distributions/meta-reference-gpu/meta_reference.py +2 -2
  66. llama_stack/distributions/meta-reference-gpu/run-with-safety.yaml +3 -2
  67. llama_stack/distributions/nvidia/{run.yaml → config.yaml} +4 -4
  68. llama_stack/distributions/nvidia/nvidia.py +1 -1
  69. llama_stack/distributions/nvidia/run-with-safety.yaml +4 -4
  70. llama_stack/{apis/datasetio → distributions/oci}/__init__.py +1 -1
  71. llama_stack/distributions/oci/config.yaml +134 -0
  72. llama_stack/distributions/oci/oci.py +108 -0
  73. llama_stack/distributions/open-benchmark/{run.yaml → config.yaml} +5 -4
  74. llama_stack/distributions/open-benchmark/open_benchmark.py +2 -3
  75. llama_stack/distributions/postgres-demo/{run.yaml → config.yaml} +4 -3
  76. llama_stack/distributions/starter/{run.yaml → config.yaml} +64 -13
  77. llama_stack/distributions/starter/run-with-postgres-store.yaml +64 -13
  78. llama_stack/distributions/starter/starter.py +8 -5
  79. llama_stack/distributions/starter-gpu/{run.yaml → config.yaml} +64 -13
  80. llama_stack/distributions/starter-gpu/run-with-postgres-store.yaml +64 -13
  81. llama_stack/distributions/template.py +13 -69
  82. llama_stack/distributions/watsonx/{run.yaml → config.yaml} +4 -3
  83. llama_stack/distributions/watsonx/watsonx.py +1 -1
  84. llama_stack/log.py +28 -11
  85. llama_stack/models/llama/checkpoint.py +6 -6
  86. llama_stack/models/llama/hadamard_utils.py +2 -0
  87. llama_stack/models/llama/llama3/generation.py +3 -1
  88. llama_stack/models/llama/llama3/interface.py +2 -5
  89. llama_stack/models/llama/llama3/multimodal/encoder_utils.py +3 -3
  90. llama_stack/models/llama/llama3/multimodal/image_transform.py +6 -6
  91. llama_stack/models/llama/llama3/prompt_templates/system_prompts.py +1 -1
  92. llama_stack/models/llama/llama3/tool_utils.py +2 -1
  93. llama_stack/models/llama/llama4/prompt_templates/system_prompts.py +1 -1
  94. llama_stack/providers/inline/agents/meta_reference/__init__.py +3 -3
  95. llama_stack/providers/inline/agents/meta_reference/agents.py +44 -261
  96. llama_stack/providers/inline/agents/meta_reference/config.py +6 -1
  97. llama_stack/providers/inline/agents/meta_reference/responses/openai_responses.py +207 -57
  98. llama_stack/providers/inline/agents/meta_reference/responses/streaming.py +308 -47
  99. llama_stack/providers/inline/agents/meta_reference/responses/tool_executor.py +162 -96
  100. llama_stack/providers/inline/agents/meta_reference/responses/types.py +23 -8
  101. llama_stack/providers/inline/agents/meta_reference/responses/utils.py +201 -33
  102. llama_stack/providers/inline/agents/meta_reference/safety.py +8 -13
  103. llama_stack/providers/inline/batches/reference/__init__.py +2 -4
  104. llama_stack/providers/inline/batches/reference/batches.py +78 -60
  105. llama_stack/providers/inline/datasetio/localfs/datasetio.py +2 -5
  106. llama_stack/providers/inline/eval/meta_reference/eval.py +16 -61
  107. llama_stack/providers/inline/files/localfs/files.py +37 -28
  108. llama_stack/providers/inline/inference/meta_reference/config.py +2 -2
  109. llama_stack/providers/inline/inference/meta_reference/generators.py +50 -60
  110. llama_stack/providers/inline/inference/meta_reference/inference.py +403 -19
  111. llama_stack/providers/inline/inference/meta_reference/model_parallel.py +7 -26
  112. llama_stack/providers/inline/inference/meta_reference/parallel_utils.py +2 -12
  113. llama_stack/providers/inline/inference/sentence_transformers/sentence_transformers.py +10 -15
  114. llama_stack/providers/inline/post_training/common/validator.py +1 -5
  115. llama_stack/providers/inline/post_training/huggingface/post_training.py +8 -8
  116. llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device.py +18 -10
  117. llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device_dpo.py +12 -9
  118. llama_stack/providers/inline/post_training/huggingface/utils.py +27 -6
  119. llama_stack/providers/inline/post_training/torchtune/common/checkpointer.py +1 -1
  120. llama_stack/providers/inline/post_training/torchtune/common/utils.py +1 -1
  121. llama_stack/providers/inline/post_training/torchtune/datasets/format_adapter.py +1 -1
  122. llama_stack/providers/inline/post_training/torchtune/post_training.py +8 -8
  123. llama_stack/providers/inline/post_training/torchtune/recipes/lora_finetuning_single_device.py +16 -16
  124. llama_stack/providers/inline/safety/code_scanner/code_scanner.py +13 -9
  125. llama_stack/providers/inline/safety/llama_guard/llama_guard.py +18 -15
  126. llama_stack/providers/inline/safety/prompt_guard/prompt_guard.py +9 -9
  127. llama_stack/providers/inline/scoring/basic/scoring.py +6 -13
  128. llama_stack/providers/inline/scoring/basic/scoring_fn/docvqa_scoring_fn.py +1 -2
  129. llama_stack/providers/inline/scoring/basic/scoring_fn/equality_scoring_fn.py +1 -2
  130. llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/docvqa.py +2 -2
  131. llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/equality.py +2 -2
  132. llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/ifeval.py +2 -2
  133. llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/regex_parser_math_response.py +2 -2
  134. llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/regex_parser_multiple_choice_answer.py +2 -2
  135. llama_stack/providers/inline/scoring/basic/scoring_fn/fn_defs/subset_of.py +2 -2
  136. llama_stack/providers/inline/scoring/basic/scoring_fn/ifeval_scoring_fn.py +1 -2
  137. llama_stack/providers/inline/scoring/basic/scoring_fn/regex_parser_math_response_scoring_fn.py +1 -2
  138. llama_stack/providers/inline/scoring/basic/scoring_fn/regex_parser_scoring_fn.py +1 -2
  139. llama_stack/providers/inline/scoring/basic/scoring_fn/subset_of_scoring_fn.py +1 -2
  140. llama_stack/providers/inline/scoring/braintrust/braintrust.py +12 -15
  141. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/answer_correctness.py +2 -2
  142. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/answer_relevancy.py +2 -2
  143. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/answer_similarity.py +2 -2
  144. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_entity_recall.py +2 -2
  145. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_precision.py +2 -2
  146. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_recall.py +2 -2
  147. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/context_relevancy.py +2 -2
  148. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/factuality.py +2 -2
  149. llama_stack/providers/inline/scoring/braintrust/scoring_fn/fn_defs/faithfulness.py +2 -2
  150. llama_stack/providers/inline/scoring/llm_as_judge/scoring.py +7 -14
  151. llama_stack/providers/inline/scoring/llm_as_judge/scoring_fn/fn_defs/llm_as_judge_405b_simpleqa.py +2 -2
  152. llama_stack/providers/inline/scoring/llm_as_judge/scoring_fn/fn_defs/llm_as_judge_base.py +1 -2
  153. llama_stack/providers/inline/scoring/llm_as_judge/scoring_fn/llm_as_judge_scoring_fn.py +1 -3
  154. llama_stack/providers/inline/tool_runtime/rag/__init__.py +1 -1
  155. llama_stack/providers/inline/tool_runtime/rag/config.py +8 -1
  156. llama_stack/providers/inline/tool_runtime/rag/context_retriever.py +7 -6
  157. llama_stack/providers/inline/tool_runtime/rag/memory.py +64 -48
  158. llama_stack/providers/inline/vector_io/chroma/__init__.py +1 -1
  159. llama_stack/providers/inline/vector_io/chroma/config.py +1 -1
  160. llama_stack/providers/inline/vector_io/faiss/__init__.py +1 -1
  161. llama_stack/providers/inline/vector_io/faiss/config.py +1 -1
  162. llama_stack/providers/inline/vector_io/faiss/faiss.py +43 -28
  163. llama_stack/providers/inline/vector_io/milvus/__init__.py +1 -1
  164. llama_stack/providers/inline/vector_io/milvus/config.py +1 -1
  165. llama_stack/providers/inline/vector_io/qdrant/__init__.py +1 -1
  166. llama_stack/providers/inline/vector_io/qdrant/config.py +1 -1
  167. llama_stack/providers/inline/vector_io/sqlite_vec/__init__.py +1 -1
  168. llama_stack/providers/inline/vector_io/sqlite_vec/sqlite_vec.py +40 -33
  169. llama_stack/providers/registry/agents.py +7 -3
  170. llama_stack/providers/registry/batches.py +1 -1
  171. llama_stack/providers/registry/datasetio.py +1 -1
  172. llama_stack/providers/registry/eval.py +1 -1
  173. llama_stack/{apis/datasets/__init__.py → providers/registry/file_processors.py} +5 -1
  174. llama_stack/providers/registry/files.py +11 -2
  175. llama_stack/providers/registry/inference.py +22 -3
  176. llama_stack/providers/registry/post_training.py +1 -1
  177. llama_stack/providers/registry/safety.py +1 -1
  178. llama_stack/providers/registry/scoring.py +1 -1
  179. llama_stack/providers/registry/tool_runtime.py +2 -2
  180. llama_stack/providers/registry/vector_io.py +7 -7
  181. llama_stack/providers/remote/datasetio/huggingface/huggingface.py +2 -5
  182. llama_stack/providers/remote/datasetio/nvidia/datasetio.py +1 -4
  183. llama_stack/providers/remote/eval/nvidia/eval.py +15 -9
  184. llama_stack/providers/remote/files/openai/__init__.py +19 -0
  185. llama_stack/providers/remote/files/openai/config.py +28 -0
  186. llama_stack/providers/remote/files/openai/files.py +253 -0
  187. llama_stack/providers/remote/files/s3/files.py +52 -30
  188. llama_stack/providers/remote/inference/anthropic/anthropic.py +2 -1
  189. llama_stack/providers/remote/inference/anthropic/config.py +1 -1
  190. llama_stack/providers/remote/inference/azure/azure.py +1 -3
  191. llama_stack/providers/remote/inference/azure/config.py +8 -7
  192. llama_stack/providers/remote/inference/bedrock/__init__.py +1 -1
  193. llama_stack/providers/remote/inference/bedrock/bedrock.py +82 -105
  194. llama_stack/providers/remote/inference/bedrock/config.py +24 -3
  195. llama_stack/providers/remote/inference/cerebras/cerebras.py +5 -5
  196. llama_stack/providers/remote/inference/cerebras/config.py +12 -5
  197. llama_stack/providers/remote/inference/databricks/config.py +13 -6
  198. llama_stack/providers/remote/inference/databricks/databricks.py +16 -6
  199. llama_stack/providers/remote/inference/fireworks/config.py +5 -5
  200. llama_stack/providers/remote/inference/fireworks/fireworks.py +1 -1
  201. llama_stack/providers/remote/inference/gemini/config.py +1 -1
  202. llama_stack/providers/remote/inference/gemini/gemini.py +13 -14
  203. llama_stack/providers/remote/inference/groq/config.py +5 -5
  204. llama_stack/providers/remote/inference/groq/groq.py +1 -1
  205. llama_stack/providers/remote/inference/llama_openai_compat/config.py +5 -5
  206. llama_stack/providers/remote/inference/llama_openai_compat/llama.py +8 -6
  207. llama_stack/providers/remote/inference/nvidia/__init__.py +1 -1
  208. llama_stack/providers/remote/inference/nvidia/config.py +21 -11
  209. llama_stack/providers/remote/inference/nvidia/nvidia.py +115 -3
  210. llama_stack/providers/remote/inference/nvidia/utils.py +1 -1
  211. llama_stack/providers/remote/inference/oci/__init__.py +17 -0
  212. llama_stack/providers/remote/inference/oci/auth.py +79 -0
  213. llama_stack/providers/remote/inference/oci/config.py +75 -0
  214. llama_stack/providers/remote/inference/oci/oci.py +162 -0
  215. llama_stack/providers/remote/inference/ollama/config.py +7 -5
  216. llama_stack/providers/remote/inference/ollama/ollama.py +17 -8
  217. llama_stack/providers/remote/inference/openai/config.py +4 -4
  218. llama_stack/providers/remote/inference/openai/openai.py +1 -1
  219. llama_stack/providers/remote/inference/passthrough/__init__.py +2 -2
  220. llama_stack/providers/remote/inference/passthrough/config.py +5 -10
  221. llama_stack/providers/remote/inference/passthrough/passthrough.py +97 -75
  222. llama_stack/providers/remote/inference/runpod/config.py +12 -5
  223. llama_stack/providers/remote/inference/runpod/runpod.py +2 -20
  224. llama_stack/providers/remote/inference/sambanova/config.py +5 -5
  225. llama_stack/providers/remote/inference/sambanova/sambanova.py +1 -1
  226. llama_stack/providers/remote/inference/tgi/config.py +7 -6
  227. llama_stack/providers/remote/inference/tgi/tgi.py +19 -11
  228. llama_stack/providers/remote/inference/together/config.py +5 -5
  229. llama_stack/providers/remote/inference/together/together.py +15 -12
  230. llama_stack/providers/remote/inference/vertexai/config.py +1 -1
  231. llama_stack/providers/remote/inference/vllm/config.py +5 -5
  232. llama_stack/providers/remote/inference/vllm/vllm.py +13 -14
  233. llama_stack/providers/remote/inference/watsonx/config.py +4 -4
  234. llama_stack/providers/remote/inference/watsonx/watsonx.py +21 -94
  235. llama_stack/providers/remote/post_training/nvidia/post_training.py +4 -4
  236. llama_stack/providers/remote/post_training/nvidia/utils.py +1 -1
  237. llama_stack/providers/remote/safety/bedrock/bedrock.py +6 -6
  238. llama_stack/providers/remote/safety/bedrock/config.py +1 -1
  239. llama_stack/providers/remote/safety/nvidia/config.py +1 -1
  240. llama_stack/providers/remote/safety/nvidia/nvidia.py +11 -5
  241. llama_stack/providers/remote/safety/sambanova/config.py +1 -1
  242. llama_stack/providers/remote/safety/sambanova/sambanova.py +6 -6
  243. llama_stack/providers/remote/tool_runtime/bing_search/bing_search.py +11 -6
  244. llama_stack/providers/remote/tool_runtime/brave_search/brave_search.py +12 -7
  245. llama_stack/providers/remote/tool_runtime/model_context_protocol/config.py +8 -2
  246. llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py +57 -15
  247. llama_stack/providers/remote/tool_runtime/tavily_search/tavily_search.py +11 -6
  248. llama_stack/providers/remote/tool_runtime/wolfram_alpha/wolfram_alpha.py +11 -6
  249. llama_stack/providers/remote/vector_io/chroma/__init__.py +1 -1
  250. llama_stack/providers/remote/vector_io/chroma/chroma.py +125 -20
  251. llama_stack/providers/remote/vector_io/chroma/config.py +1 -1
  252. llama_stack/providers/remote/vector_io/milvus/__init__.py +1 -1
  253. llama_stack/providers/remote/vector_io/milvus/config.py +1 -1
  254. llama_stack/providers/remote/vector_io/milvus/milvus.py +27 -21
  255. llama_stack/providers/remote/vector_io/pgvector/__init__.py +1 -1
  256. llama_stack/providers/remote/vector_io/pgvector/config.py +1 -1
  257. llama_stack/providers/remote/vector_io/pgvector/pgvector.py +26 -18
  258. llama_stack/providers/remote/vector_io/qdrant/__init__.py +1 -1
  259. llama_stack/providers/remote/vector_io/qdrant/config.py +1 -1
  260. llama_stack/providers/remote/vector_io/qdrant/qdrant.py +141 -24
  261. llama_stack/providers/remote/vector_io/weaviate/__init__.py +1 -1
  262. llama_stack/providers/remote/vector_io/weaviate/config.py +1 -1
  263. llama_stack/providers/remote/vector_io/weaviate/weaviate.py +26 -21
  264. llama_stack/providers/utils/common/data_schema_validator.py +1 -5
  265. llama_stack/providers/utils/files/form_data.py +1 -1
  266. llama_stack/providers/utils/inference/embedding_mixin.py +1 -1
  267. llama_stack/providers/utils/inference/inference_store.py +12 -21
  268. llama_stack/providers/utils/inference/litellm_openai_mixin.py +79 -79
  269. llama_stack/providers/utils/inference/model_registry.py +1 -3
  270. llama_stack/providers/utils/inference/openai_compat.py +44 -1171
  271. llama_stack/providers/utils/inference/openai_mixin.py +68 -42
  272. llama_stack/providers/utils/inference/prompt_adapter.py +50 -265
  273. llama_stack/providers/utils/inference/stream_utils.py +23 -0
  274. llama_stack/providers/utils/memory/__init__.py +2 -0
  275. llama_stack/providers/utils/memory/file_utils.py +1 -1
  276. llama_stack/providers/utils/memory/openai_vector_store_mixin.py +181 -84
  277. llama_stack/providers/utils/memory/vector_store.py +39 -38
  278. llama_stack/providers/utils/pagination.py +1 -1
  279. llama_stack/providers/utils/responses/responses_store.py +15 -25
  280. llama_stack/providers/utils/scoring/aggregation_utils.py +1 -2
  281. llama_stack/providers/utils/scoring/base_scoring_fn.py +1 -2
  282. llama_stack/providers/utils/tools/mcp.py +93 -11
  283. llama_stack/telemetry/constants.py +27 -0
  284. llama_stack/telemetry/helpers.py +43 -0
  285. llama_stack/testing/api_recorder.py +25 -16
  286. {llama_stack-0.3.4.dist-info → llama_stack-0.4.0.dist-info}/METADATA +56 -131
  287. llama_stack-0.4.0.dist-info/RECORD +588 -0
  288. llama_stack-0.4.0.dist-info/top_level.txt +2 -0
  289. llama_stack_api/__init__.py +945 -0
  290. llama_stack_api/admin/__init__.py +45 -0
  291. llama_stack_api/admin/api.py +72 -0
  292. llama_stack_api/admin/fastapi_routes.py +117 -0
  293. llama_stack_api/admin/models.py +113 -0
  294. llama_stack_api/agents.py +173 -0
  295. llama_stack_api/batches/__init__.py +40 -0
  296. llama_stack_api/batches/api.py +53 -0
  297. llama_stack_api/batches/fastapi_routes.py +113 -0
  298. llama_stack_api/batches/models.py +78 -0
  299. llama_stack_api/benchmarks/__init__.py +43 -0
  300. llama_stack_api/benchmarks/api.py +39 -0
  301. llama_stack_api/benchmarks/fastapi_routes.py +109 -0
  302. llama_stack_api/benchmarks/models.py +109 -0
  303. {llama_stack/apis → llama_stack_api}/common/content_types.py +1 -43
  304. {llama_stack/apis → llama_stack_api}/common/errors.py +0 -8
  305. {llama_stack/apis → llama_stack_api}/common/job_types.py +1 -1
  306. llama_stack_api/common/responses.py +77 -0
  307. {llama_stack/apis → llama_stack_api}/common/training_types.py +1 -1
  308. {llama_stack/apis → llama_stack_api}/common/type_system.py +2 -14
  309. llama_stack_api/connectors.py +146 -0
  310. {llama_stack/apis/conversations → llama_stack_api}/conversations.py +23 -39
  311. {llama_stack/apis/datasetio → llama_stack_api}/datasetio.py +4 -8
  312. llama_stack_api/datasets/__init__.py +61 -0
  313. llama_stack_api/datasets/api.py +35 -0
  314. llama_stack_api/datasets/fastapi_routes.py +104 -0
  315. llama_stack_api/datasets/models.py +152 -0
  316. {llama_stack/providers → llama_stack_api}/datatypes.py +166 -10
  317. {llama_stack/apis/eval → llama_stack_api}/eval.py +8 -40
  318. llama_stack_api/file_processors/__init__.py +27 -0
  319. llama_stack_api/file_processors/api.py +64 -0
  320. llama_stack_api/file_processors/fastapi_routes.py +78 -0
  321. llama_stack_api/file_processors/models.py +42 -0
  322. llama_stack_api/files/__init__.py +35 -0
  323. llama_stack_api/files/api.py +51 -0
  324. llama_stack_api/files/fastapi_routes.py +124 -0
  325. llama_stack_api/files/models.py +107 -0
  326. {llama_stack/apis/inference → llama_stack_api}/inference.py +90 -194
  327. llama_stack_api/inspect_api/__init__.py +37 -0
  328. llama_stack_api/inspect_api/api.py +25 -0
  329. llama_stack_api/inspect_api/fastapi_routes.py +76 -0
  330. llama_stack_api/inspect_api/models.py +28 -0
  331. {llama_stack/apis/agents → llama_stack_api/internal}/__init__.py +3 -1
  332. llama_stack/providers/utils/kvstore/api.py → llama_stack_api/internal/kvstore.py +5 -0
  333. llama_stack_api/internal/sqlstore.py +79 -0
  334. {llama_stack/apis/models → llama_stack_api}/models.py +11 -9
  335. {llama_stack/apis/agents → llama_stack_api}/openai_responses.py +184 -27
  336. {llama_stack/apis/post_training → llama_stack_api}/post_training.py +7 -11
  337. {llama_stack/apis/prompts → llama_stack_api}/prompts.py +3 -4
  338. llama_stack_api/providers/__init__.py +33 -0
  339. llama_stack_api/providers/api.py +16 -0
  340. llama_stack_api/providers/fastapi_routes.py +57 -0
  341. llama_stack_api/providers/models.py +24 -0
  342. {llama_stack/apis/tools → llama_stack_api}/rag_tool.py +2 -52
  343. {llama_stack/apis → llama_stack_api}/resource.py +1 -1
  344. llama_stack_api/router_utils.py +160 -0
  345. {llama_stack/apis/safety → llama_stack_api}/safety.py +6 -9
  346. {llama_stack → llama_stack_api}/schema_utils.py +94 -4
  347. {llama_stack/apis/scoring → llama_stack_api}/scoring.py +3 -3
  348. {llama_stack/apis/scoring_functions → llama_stack_api}/scoring_functions.py +9 -6
  349. {llama_stack/apis/shields → llama_stack_api}/shields.py +6 -7
  350. {llama_stack/apis/tools → llama_stack_api}/tools.py +26 -21
  351. {llama_stack/apis/vector_io → llama_stack_api}/vector_io.py +133 -152
  352. {llama_stack/apis/vector_stores → llama_stack_api}/vector_stores.py +1 -1
  353. llama_stack/apis/agents/agents.py +0 -894
  354. llama_stack/apis/batches/__init__.py +0 -9
  355. llama_stack/apis/batches/batches.py +0 -100
  356. llama_stack/apis/benchmarks/__init__.py +0 -7
  357. llama_stack/apis/benchmarks/benchmarks.py +0 -108
  358. llama_stack/apis/common/responses.py +0 -36
  359. llama_stack/apis/conversations/__init__.py +0 -31
  360. llama_stack/apis/datasets/datasets.py +0 -251
  361. llama_stack/apis/datatypes.py +0 -160
  362. llama_stack/apis/eval/__init__.py +0 -7
  363. llama_stack/apis/files/__init__.py +0 -7
  364. llama_stack/apis/files/files.py +0 -199
  365. llama_stack/apis/inference/__init__.py +0 -7
  366. llama_stack/apis/inference/event_logger.py +0 -43
  367. llama_stack/apis/inspect/__init__.py +0 -7
  368. llama_stack/apis/inspect/inspect.py +0 -94
  369. llama_stack/apis/models/__init__.py +0 -7
  370. llama_stack/apis/post_training/__init__.py +0 -7
  371. llama_stack/apis/prompts/__init__.py +0 -9
  372. llama_stack/apis/providers/__init__.py +0 -7
  373. llama_stack/apis/providers/providers.py +0 -69
  374. llama_stack/apis/safety/__init__.py +0 -7
  375. llama_stack/apis/scoring/__init__.py +0 -7
  376. llama_stack/apis/scoring_functions/__init__.py +0 -7
  377. llama_stack/apis/shields/__init__.py +0 -7
  378. llama_stack/apis/synthetic_data_generation/__init__.py +0 -7
  379. llama_stack/apis/synthetic_data_generation/synthetic_data_generation.py +0 -77
  380. llama_stack/apis/telemetry/__init__.py +0 -7
  381. llama_stack/apis/telemetry/telemetry.py +0 -423
  382. llama_stack/apis/tools/__init__.py +0 -8
  383. llama_stack/apis/vector_io/__init__.py +0 -7
  384. llama_stack/apis/vector_stores/__init__.py +0 -7
  385. llama_stack/core/server/tracing.py +0 -80
  386. llama_stack/core/ui/app.py +0 -55
  387. llama_stack/core/ui/modules/__init__.py +0 -5
  388. llama_stack/core/ui/modules/api.py +0 -32
  389. llama_stack/core/ui/modules/utils.py +0 -42
  390. llama_stack/core/ui/page/__init__.py +0 -5
  391. llama_stack/core/ui/page/distribution/__init__.py +0 -5
  392. llama_stack/core/ui/page/distribution/datasets.py +0 -18
  393. llama_stack/core/ui/page/distribution/eval_tasks.py +0 -20
  394. llama_stack/core/ui/page/distribution/models.py +0 -18
  395. llama_stack/core/ui/page/distribution/providers.py +0 -27
  396. llama_stack/core/ui/page/distribution/resources.py +0 -48
  397. llama_stack/core/ui/page/distribution/scoring_functions.py +0 -18
  398. llama_stack/core/ui/page/distribution/shields.py +0 -19
  399. llama_stack/core/ui/page/evaluations/__init__.py +0 -5
  400. llama_stack/core/ui/page/evaluations/app_eval.py +0 -143
  401. llama_stack/core/ui/page/evaluations/native_eval.py +0 -253
  402. llama_stack/core/ui/page/playground/__init__.py +0 -5
  403. llama_stack/core/ui/page/playground/chat.py +0 -130
  404. llama_stack/core/ui/page/playground/tools.py +0 -352
  405. llama_stack/distributions/dell/build.yaml +0 -33
  406. llama_stack/distributions/meta-reference-gpu/build.yaml +0 -32
  407. llama_stack/distributions/nvidia/build.yaml +0 -29
  408. llama_stack/distributions/open-benchmark/build.yaml +0 -36
  409. llama_stack/distributions/postgres-demo/__init__.py +0 -7
  410. llama_stack/distributions/postgres-demo/build.yaml +0 -23
  411. llama_stack/distributions/postgres-demo/postgres_demo.py +0 -125
  412. llama_stack/distributions/starter/build.yaml +0 -61
  413. llama_stack/distributions/starter-gpu/build.yaml +0 -61
  414. llama_stack/distributions/watsonx/build.yaml +0 -33
  415. llama_stack/providers/inline/agents/meta_reference/agent_instance.py +0 -1024
  416. llama_stack/providers/inline/agents/meta_reference/persistence.py +0 -228
  417. llama_stack/providers/inline/telemetry/__init__.py +0 -5
  418. llama_stack/providers/inline/telemetry/meta_reference/__init__.py +0 -21
  419. llama_stack/providers/inline/telemetry/meta_reference/config.py +0 -47
  420. llama_stack/providers/inline/telemetry/meta_reference/telemetry.py +0 -252
  421. llama_stack/providers/remote/inference/bedrock/models.py +0 -29
  422. llama_stack/providers/utils/kvstore/sqlite/config.py +0 -20
  423. llama_stack/providers/utils/sqlstore/__init__.py +0 -5
  424. llama_stack/providers/utils/sqlstore/api.py +0 -128
  425. llama_stack/providers/utils/telemetry/__init__.py +0 -5
  426. llama_stack/providers/utils/telemetry/trace_protocol.py +0 -142
  427. llama_stack/providers/utils/telemetry/tracing.py +0 -384
  428. llama_stack/strong_typing/__init__.py +0 -19
  429. llama_stack/strong_typing/auxiliary.py +0 -228
  430. llama_stack/strong_typing/classdef.py +0 -440
  431. llama_stack/strong_typing/core.py +0 -46
  432. llama_stack/strong_typing/deserializer.py +0 -877
  433. llama_stack/strong_typing/docstring.py +0 -409
  434. llama_stack/strong_typing/exception.py +0 -23
  435. llama_stack/strong_typing/inspection.py +0 -1085
  436. llama_stack/strong_typing/mapping.py +0 -40
  437. llama_stack/strong_typing/name.py +0 -182
  438. llama_stack/strong_typing/schema.py +0 -792
  439. llama_stack/strong_typing/serialization.py +0 -97
  440. llama_stack/strong_typing/serializer.py +0 -500
  441. llama_stack/strong_typing/slots.py +0 -27
  442. llama_stack/strong_typing/topological.py +0 -89
  443. llama_stack/ui/node_modules/flatted/python/flatted.py +0 -149
  444. llama_stack-0.3.4.dist-info/RECORD +0 -625
  445. llama_stack-0.3.4.dist-info/top_level.txt +0 -1
  446. /llama_stack/{providers/utils → core/storage}/kvstore/config.py +0 -0
  447. /llama_stack/{providers/utils → core/storage}/kvstore/mongodb/__init__.py +0 -0
  448. /llama_stack/{providers/utils → core/storage}/kvstore/postgres/__init__.py +0 -0
  449. /llama_stack/{providers/utils → core/storage}/kvstore/redis/__init__.py +0 -0
  450. /llama_stack/{providers/utils → core/storage}/kvstore/sqlite/__init__.py +0 -0
  451. /llama_stack/{apis → providers/inline/file_processor}/__init__.py +0 -0
  452. /llama_stack/{apis/common → telemetry}/__init__.py +0 -0
  453. {llama_stack-0.3.4.dist-info → llama_stack-0.4.0.dist-info}/WHEEL +0 -0
  454. {llama_stack-0.3.4.dist-info → llama_stack-0.4.0.dist-info}/entry_points.txt +0 -0
  455. {llama_stack-0.3.4.dist-info → llama_stack-0.4.0.dist-info}/licenses/LICENSE +0 -0
  456. {llama_stack/core/ui → llama_stack_api/common}/__init__.py +0 -0
  457. {llama_stack/strong_typing → llama_stack_api}/py.typed +0 -0
  458. {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,5 +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.
@@ -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"