siili-ai-sdk 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. siili_ai_sdk-0.5.0/.cursor/rules/global.mdc +32 -0
  2. siili_ai_sdk-0.5.0/.cursor/rules/post_run.mdc +14 -0
  3. siili_ai_sdk-0.5.0/.cursor/rules/repo_overview.mdc +84 -0
  4. siili_ai_sdk-0.5.0/.cursor/rules/testing-structure.mdc +54 -0
  5. siili_ai_sdk-0.5.0/.gitignore +41 -0
  6. siili_ai_sdk-0.5.0/Makefile +92 -0
  7. siili_ai_sdk-0.5.0/PKG-INFO +249 -0
  8. siili_ai_sdk-0.5.0/README.md +196 -0
  9. siili_ai_sdk-0.5.0/__init__.py.bak +20 -0
  10. siili_ai_sdk-0.5.0/env.example +28 -0
  11. siili_ai_sdk-0.5.0/kill.sh +39 -0
  12. siili_ai_sdk-0.5.0/py.typed +1 -0
  13. siili_ai_sdk-0.5.0/pyproject.toml +147 -0
  14. siili_ai_sdk-0.5.0/setup.sh +11 -0
  15. siili_ai_sdk-0.5.0/siili_ai_sdk/__init__.py +21 -0
  16. siili_ai_sdk-0.5.0/siili_ai_sdk/agent/__init__.py +0 -0
  17. siili_ai_sdk-0.5.0/siili_ai_sdk/agent/base_agent.py +205 -0
  18. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/__init__.py +22 -0
  19. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/builder.py +61 -0
  20. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/file_storage_provider.py +27 -0
  21. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/mime_types.py +118 -0
  22. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/models.py +63 -0
  23. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/provider_support.py +53 -0
  24. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/__init__.py +0 -0
  25. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/base_file_storage.py +32 -0
  26. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/impl/__init__.py +0 -0
  27. siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/impl/local_file_storage.py +101 -0
  28. siili_ai_sdk-0.5.0/siili_ai_sdk/config/credentials_provider.py +10 -0
  29. siili_ai_sdk-0.5.0/siili_ai_sdk/config/env.py +55 -0
  30. siili_ai_sdk-0.5.0/siili_ai_sdk/config/env_credentials_provider.py +7 -0
  31. siili_ai_sdk-0.5.0/siili_ai_sdk/config/get_credentials_provider.py +14 -0
  32. siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/__init__.py +9 -0
  33. siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/image_generator.py +83 -0
  34. siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/options.py +24 -0
  35. siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/providers/__init__.py +0 -0
  36. siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/providers/google.py +75 -0
  37. siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/providers/openai.py +60 -0
  38. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/__init__.py +0 -0
  39. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cancellation_handle.py +10 -0
  40. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/__init__.py +0 -0
  41. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/consumption_estimate.py +26 -0
  42. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/consumption_estimate_builder.py +113 -0
  43. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/consumption_extractor.py +59 -0
  44. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/token_usage.py +31 -0
  45. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/converters.py +146 -0
  46. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/__init__.py +1 -0
  47. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/builtin_cost_provider.py +83 -0
  48. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/cost_estimate.py +8 -0
  49. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/cost_provider.py +28 -0
  50. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/extract_error_message.py +37 -0
  51. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/langchain_loop_manager.py +270 -0
  52. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/langchain_service.py +195 -0
  53. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/message_handler.py +188 -0
  54. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/__init__.py +1 -0
  55. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/block_manager.py +152 -0
  56. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/models.py +42 -0
  57. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/streaming_content_handler.py +157 -0
  58. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/streaming_event_handler.py +215 -0
  59. siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/streaming_state_manager.py +58 -0
  60. siili_ai_sdk-0.5.0/siili_ai_sdk/models/__init__.py +0 -0
  61. siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/__init__.py +0 -0
  62. siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/anthropic_factory.py +33 -0
  63. siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/base_model_factory.py +71 -0
  64. siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/google_factory.py +30 -0
  65. siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/ollama_factory.py +41 -0
  66. siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/openai_factory.py +50 -0
  67. siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_config.py +46 -0
  68. siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_families.py +7 -0
  69. siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_model.py +17 -0
  70. siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_wrapper.py +25 -0
  71. siili_ai_sdk-0.5.0/siili_ai_sdk/models/model_registry.py +156 -0
  72. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/__init__.py +0 -0
  73. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/anthropic_provider.py +29 -0
  74. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/azure_provider.py +31 -0
  75. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/base_provider.py +62 -0
  76. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/google_provider.py +26 -0
  77. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/ollama_provider.py +26 -0
  78. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/openai_provider.py +26 -0
  79. siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/provider_type.py +90 -0
  80. siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/__init__.py +0 -0
  81. siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/get_prompt_loader.py +13 -0
  82. siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/local_prompt_loader.py +21 -0
  83. siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/prompt_loader.py +48 -0
  84. siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/prompt_loader_mode.py +14 -0
  85. siili_ai_sdk-0.5.0/siili_ai_sdk/py.typed +1 -0
  86. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/__init__.py +1 -0
  87. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/base_playback.py +90 -0
  88. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/base_recorder.py +50 -0
  89. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/conditional_recorder.py +38 -0
  90. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/impl/__init__.py +1 -0
  91. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/impl/local_playback.py +76 -0
  92. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/impl/local_recorder.py +85 -0
  93. siili_ai_sdk-0.5.0/siili_ai_sdk/recording/langchain_serializer.py +88 -0
  94. siili_ai_sdk-0.5.0/siili_ai_sdk/server/__init__.py +1 -0
  95. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/__init__.py +0 -0
  96. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/api_builder.py +126 -0
  97. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/file_router_factory.py +111 -0
  98. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/thread_router_factory.py +267 -0
  99. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/__init__.py +0 -0
  100. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/format_sse_event.py +41 -0
  101. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/negotiate_streaming_response.py +8 -0
  102. siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/streaming_negotiator.py +10 -0
  103. siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/__init__.py +0 -0
  104. siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/base_authorizer.py +61 -0
  105. siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/base_user.py +13 -0
  106. siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/dummy_authorizer.py +17 -0
  107. siili_ai_sdk-0.5.0/siili_ai_sdk/server/job_processor/__init__.py +0 -0
  108. siili_ai_sdk-0.5.0/siili_ai_sdk/server/job_processor/base_job_processor.py +8 -0
  109. siili_ai_sdk-0.5.0/siili_ai_sdk/server/job_processor/thread_job_processor.py +32 -0
  110. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/__init__.py +1 -0
  111. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/cancellation_publisher.py +7 -0
  112. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/cancellation_subscriber.py +37 -0
  113. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/event_publisher.py +13 -0
  114. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/impl/__init__.py +1 -0
  115. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/impl/local_cancellation_pubsub.py +48 -0
  116. siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/impl/signalr_publisher.py +36 -0
  117. siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/__init__.py +1 -0
  118. siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/agent_job_queue.py +27 -0
  119. siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/impl/__init__.py +1 -0
  120. siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/impl/azure_queue.py +24 -0
  121. siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/__init__.py +0 -0
  122. siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/agent_response_generator.py +39 -0
  123. siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/response_generator.py +13 -0
  124. siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/simple_agent_response_generator.py +14 -0
  125. siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/__init__.py +0 -0
  126. siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/thread_converters.py +113 -0
  127. siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/thread_models.py +90 -0
  128. siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/thread_service.py +91 -0
  129. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/__init__.py +1 -0
  130. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/base_thread_repository.py +51 -0
  131. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/impl/__init__.py +0 -0
  132. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/impl/in_memory_thread_repository.py +100 -0
  133. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/impl/local_file_thread_repository.py +217 -0
  134. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/thread_filter.py +166 -0
  135. siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/thread_metadata.py +53 -0
  136. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/__init__.py +0 -0
  137. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/__init__.py +0 -0
  138. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/__init__.py +0 -0
  139. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/block_display.py +92 -0
  140. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/display_manager.py +84 -0
  141. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/live_cli.py +235 -0
  142. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/event_adapter.py +28 -0
  143. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/streaming_block_adapter.py +57 -0
  144. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/sync_adapter.py +76 -0
  145. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/models.py +224 -0
  146. siili_ai_sdk-0.5.0/siili_ai_sdk/thread/thread_container.py +467 -0
  147. siili_ai_sdk-0.5.0/siili_ai_sdk/tools/__init__.py +0 -0
  148. siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/__init__.py +0 -0
  149. siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/crawl_tool_provider.py +19 -0
  150. siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/mcp_tool_provider.py +93 -0
  151. siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/search_tool_provider.py +18 -0
  152. siili_ai_sdk-0.5.0/siili_ai_sdk/tools/tool_provider.py +131 -0
  153. siili_ai_sdk-0.5.0/siili_ai_sdk/tracing/__init__.py +0 -0
  154. siili_ai_sdk-0.5.0/siili_ai_sdk/tracing/agent_trace.py +79 -0
  155. siili_ai_sdk-0.5.0/siili_ai_sdk/utils/__init__.py +0 -0
  156. siili_ai_sdk-0.5.0/siili_ai_sdk/utils/init_logger.py +24 -0
  157. siili_ai_sdk-0.5.0/tests/__init__.py +0 -0
  158. siili_ai_sdk-0.5.0/tests/conftest.py +0 -0
  159. siili_ai_sdk-0.5.0/tests/data/recordings/test_consumption_tracking/1.jsonl +6 -0
  160. siili_ai_sdk-0.5.0/tests/data/recordings/test_event_stream_basic/1.jsonl +6 -0
  161. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text/1.jsonl +6 -0
  162. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-3-7-sonnet-latest/1.jsonl +6 -0
  163. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-haiku-4-5-20251001/1.jsonl +6 -0
  164. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-opus-4-5-20251101/1.jsonl +32 -0
  165. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-sonnet-4-20250514/1.jsonl +6 -0
  166. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-sonnet-4-5-20250929/1.jsonl +6 -0
  167. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gemini-2.5-flash/1.jsonl +6 -0
  168. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gemini-3-flash-preview/1.jsonl +19 -0
  169. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gemini-3-pro-preview/1.jsonl +20 -0
  170. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gpt-4.1/1.jsonl +6 -0
  171. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gpt-5.1/1.jsonl +31 -0
  172. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gpt-5.2/1.jsonl +30 -0
  173. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_o4-mini/1.jsonl +6 -0
  174. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_with_cancellation/1.jsonl +6 -0
  175. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-3-7-sonnet-latest/1.jsonl +16 -0
  176. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-haiku-4-5-20251001/1.jsonl +16 -0
  177. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-opus-4-1-20250805/1.jsonl +16 -0
  178. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-opus-4-5-20251101/1.jsonl +53 -0
  179. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-sonnet-4-20250514/1.jsonl +16 -0
  180. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-sonnet-4-5-20250929/1.jsonl +16 -0
  181. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gemini-2.5-flash/1.jsonl +16 -0
  182. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gemini-3-flash-preview/1.jsonl +44 -0
  183. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-4.1/1.jsonl +16 -0
  184. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5/1.jsonl +16 -0
  185. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.1/1.jsonl +142 -0
  186. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.1-codex/1.jsonl +64 -0
  187. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.2/1.jsonl +58 -0
  188. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.2-pro/1.jsonl +46 -0
  189. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_o4-mini/1.jsonl +16 -0
  190. siili_ai_sdk-0.5.0/tests/data/recordings/test_get_structured_response/1.json +4 -0
  191. siili_ai_sdk-0.5.0/tests/data/recordings/test_mystery_streaming_issue/1.jsonl +6 -0
  192. siili_ai_sdk-0.5.0/tests/integration/__init__.py +0 -0
  193. siili_ai_sdk-0.5.0/tests/integration/test_cost_tracking_integration.py +79 -0
  194. siili_ai_sdk-0.5.0/tests/integration/test_mcp_tool_provider.py +68 -0
  195. siili_ai_sdk-0.5.0/tests/manual/__init__.py +0 -0
  196. siili_ai_sdk-0.5.0/tests/manual/test_crawl.py +22 -0
  197. siili_ai_sdk-0.5.0/tests/manual/test_search.py +22 -0
  198. siili_ai_sdk-0.5.0/tests/unit/__init__.py +0 -0
  199. siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/agent/test_base_agent.py +277 -0
  200. siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/llm/streaming/test_streaming_event_handler.py +221 -0
  201. siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/models/__init__.py +0 -0
  202. siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/models/test_model_registry.py +76 -0
  203. siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/tools/impl/__init__.py +0 -0
  204. siili_ai_sdk-0.5.0/uv.lock +5051 -0
@@ -0,0 +1,32 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+ # General
7
+
8
+ this project is a helper SDK for building various kinds of agentic + ai solutions
9
+
10
+ main goal is to give good DX and make it fast and easy to build POCs that also are of good quality
11
+ and something you can easily get to production as well
12
+
13
+
14
+ # style stuff:
15
+
16
+ - use absolute imports
17
+ - comments are a code smell, avoid docstrings too if not adding anything
18
+ - empty __init__.py unless otherwise specified
19
+ - no star imports
20
+ - always use types
21
+ - use uv and ruff
22
+
23
+
24
+ # logging
25
+
26
+ this is the way to obtain the logger:
27
+
28
+ ```
29
+ from siili_ai_sdk.utils.init_logger import init_logger
30
+
31
+ logger = init_logger(__name__)
32
+ ```
@@ -0,0 +1,14 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ After you have done something substantial (eg. touching multiple files):
8
+
9
+ First, take a look at the code you wrote. Does it look clean an elegant with good separation of concerns and small files and small methods. If not, go clean it up. Also make sure you don't have any inline imports etc smelly stuff.
10
+
11
+ Then run this command to make sure everything is ok:
12
+
13
+ `make lint-fix && make typecheck && make test-unit`
14
+
@@ -0,0 +1,84 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+ # Agent SDK - Repository Overview
7
+
8
+ This is a Python-based Agent SDK for building various kinds of agentic + AI solutions. The main goal is to provide good DX (Developer Experience) and make it fast and easy to build POCs that are also of good quality and can easily transition to production.
9
+
10
+ ## Core Purpose & Philosophy
11
+
12
+ - **Helper SDK** for building agentic + AI solutions
13
+ - **Fast POC Development** that scales to production quality
14
+ - **Good DX** with clean abstractions and patterns
15
+ - **Multi-LLM Support** with unified interface
16
+ - **Streaming & Interactive** capabilities built-in
17
+
18
+ ## Project Structure & Key Components
19
+
20
+ ### Entry Points
21
+ - **[main.py](mdc:main.py)** - Main application entry point, demonstrates DemoAgent and MinimalAgent usage
22
+ - **[setup.sh](mdc:setup.sh)** - Development environment setup script
23
+
24
+ ### Core Architecture Modules
25
+
26
+ #### **Agent System** (`app/agent/`)
27
+ - **[app/agent/base_agent.py](mdc:app/agent/base_agent.py)** - BaseAgent class providing foundation for all agents
28
+ - **[app/demo_agents/](mdc:app/demo_agents)** - Example agent implementations (DemoAgent, MinimalAgent)
29
+
30
+ #### **LLM Integration** (`app/models/`)
31
+ Multi-provider LLM support with factory pattern:
32
+ - **Supported Providers**: Anthropic (Claude), OpenAI (GPT), Google (Gemini), Azure AI Foundry
33
+ - **[app/models/llm_types.py](mdc:app/models/llm_types.py)** - Model enums and provider types
34
+ - **[app/models/llm_config.py](mdc:app/models/llm_config.py)** - LLM configuration dataclass
35
+ - **[app/models/factories/](mdc:app/models/factories)** - Model factory implementations per provider
36
+ - **[app/models/providers/](mdc:app/models/providers)** - Provider-specific API integrations
37
+
38
+ #### **LangChain Service Layer** (`app/llm/`)
39
+ - **[app/llm/langchain_service.py](mdc:app/llm/langchain_service.py)** - Core service wrapping LangChain functionality
40
+ - **[app/llm/message_handler.py](mdc:app/llm/message_handler.py)** - Conversation history and message processing
41
+ - **[app/llm/streaming/](mdc:app/llm/streaming)** - Streaming response handling components
42
+
43
+ #### **Thread Management** (`app/thread/`)
44
+ - **[app/thread/thread_container.py](mdc:app/thread/thread_container.py)** - Core conversation state management
45
+ - **[app/thread/models.py](mdc:app/thread/models.py)** - Message, block, and event data models
46
+ - **[app/thread/adapters/](mdc:app/thread/adapters)** - Different interaction interfaces (sync, CLI)
47
+
48
+ #### **Tool System** (`app/tools/`)
49
+ - **[app/tools/tool_provider.py](mdc:app/tools/tool_provider.py)** - Abstract base for creating agent tools
50
+ - Supports LangChain BaseTool integration with Pydantic schemas
51
+
52
+ #### **Configuration & Infrastructure**
53
+ - **[config/env.py](mdc:config/env.py)** - Environment variable management
54
+ - **[app/prompt/prompt_loader.py](mdc:app/prompt/prompt_loader.py)** - Static prompt loading from markdown
55
+ - **[app/tracing/agent_trace.py](mdc:app/tracing/agent_trace.py)** - Execution tracing for debugging
56
+ - **[app/utils/init_logger.py](mdc:app/utils/init_logger.py)** - Logging utilities
57
+
58
+ ## Key Technologies & Dependencies
59
+
60
+ - **Python 3.10+** with modern async/await patterns
61
+ - **LangChain** - Primary framework for LLM orchestration
62
+ - **LangGraph** - For stateful, multi-actor applications
63
+ - **FastAPI** - Web framework for API endpoints
64
+ - **Pydantic** - Data validation and settings management
65
+ - **uv** - Fast Python package manager and runner
66
+ - **ruff** - Fast Python linter and formatter
67
+
68
+ ## Architectural Patterns
69
+
70
+ 1. **Agent-Based Architecture** - BaseAgent foundation with concrete implementations
71
+ 2. **Factory Pattern** - For LLM provider instantiation
72
+ 3. **Provider Pattern** - Unified interface across different LLM APIs
73
+ 4. **Event-Driven** - ThreadContainer publishes events for real-time updates
74
+ 5. **Streaming-First** - Built-in support for streaming responses
75
+ 6. **Tool Integration** - LangChain tool ecosystem integration
76
+ 7. **Modular Design** - Clear separation of concerns across modules
77
+
78
+ ## Development Standards
79
+
80
+ - **Absolute imports** - No relative imports
81
+ - **Type annotations** - Always use types
82
+ - **Minimal comments** - Code should be self-documenting
83
+ - **Empty `__init__.py`** - Unless otherwise specified
84
+ - **uv + ruff** - Package management and linting
@@ -0,0 +1,54 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+ # Testing Structure
7
+
8
+ ## Unit Tests
9
+ - Location: `tests/unit/{folder path to file being tested}/test_{filename}.py`
10
+ - Example: For `siili_ai_sdk/agent/base_agent.py` → `tests/unit/siili_ai_sdk/agent/test_base_agent.py`
11
+ - Use `@pytest.mark.unit` decorator
12
+ - Mock external dependencies
13
+
14
+ ## Integration Tests
15
+ - Location: `tests/integration/` (freeform structure)
16
+ - Use `@pytest.mark.integration` decorator
17
+ - Test complete workflows and component interactions
18
+
19
+ ## Test Configuration
20
+ - Main config in [pyproject.toml](mdc:pyproject.toml) under `[tool.pytest.ini_options]`
21
+ - Shared fixtures in [tests/conftest.py](mdc:tests/conftest.py)
22
+ - Test utilities in [tests/utils.py](mdc:tests/utils.py)
23
+
24
+ ## Running Tests
25
+ - Use [Makefile](mdc:Makefile) commands: `make test`, `make test-unit`, `make test-integration`
26
+ - Or directly: `uv run pytest`
27
+
28
+
29
+ ## Philosophy
30
+ - test the public interface, not the implementation and how its coded
31
+ - don't add stupid do-nothing tests that just check completely trivial aspects
32
+
33
+ Example offender:
34
+ ```
35
+ def test_valid_config_creation(self):
36
+ """Test creating a valid LLMConfig."""
37
+ config = LLMConfig(
38
+ model=LLMModel.CLAUDE_3_HAIKU,
39
+ provider_type=ProviderType.ANTHROPIC,
40
+ reasoning=True,
41
+ tool_usage=False
42
+ )
43
+
44
+ assert config.model == LLMModel.CLAUDE_3_HAIKU
45
+ assert config.provider_type == ProviderType.ANTHROPIC
46
+ assert config.reasoning is True
47
+ assert config.tool_usage is False
48
+ ```
49
+
50
+ The above is 100% pollution in the codebase and gives us absolutely no guarantees of things working.
51
+
52
+ Focus on corner cases and things that might actually break. Do NOT aim for 100% coverage or any such nonsense.
53
+
54
+ We want to test things that might actually break and test them well (not just the happy paths)
@@ -0,0 +1,41 @@
1
+ # Dependencies
2
+ node_modules
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Production
7
+ # dist
8
+ build
9
+
10
+ # Testing
11
+ coverage
12
+
13
+ # Misc
14
+ .DS_Store
15
+ .env
16
+ .env.local
17
+ .env.development.local
18
+ .env.test.local
19
+ .env.production.local
20
+
21
+ # Logs
22
+ npm-debug.log*
23
+ yarn-debug.log*
24
+ yarn-error.log*
25
+
26
+ # Editor
27
+ .vscode/*
28
+ !.vscode/extensions.json
29
+ .idea
30
+ *.suo
31
+ *.ntvs*
32
+ *.njsproj
33
+ *.sln
34
+ *.sw?
35
+ venv
36
+ __pycache__
37
+ .aider*
38
+
39
+ traces/*
40
+ data/*
41
+ recordings/*
@@ -0,0 +1,92 @@
1
+ # Makefile for Agent SDK Testing
2
+
3
+ .PHONY: test test-unit test-integration test-watch test-cov test-fast help clean lint lint-fix typecheck
4
+
5
+ # Default target
6
+ help:
7
+ @echo "Available targets:"
8
+ @echo " test - Run all tests"
9
+ @echo " test-unit - Run only unit tests"
10
+ @echo " test-unit-single - Run single unit test by pattern"
11
+ @echo " test-integration - Run only integration tests"
12
+ @echo " test-fast - Run fast tests (exclude slow tests)"
13
+ @echo " test-watch - Run tests in watch mode"
14
+ @echo " test-cov - Run tests with coverage report"
15
+ @echo " test-html - Run tests with HTML coverage report"
16
+ @echo " lint - Run linting checks"
17
+ @echo " lint-fix - Run linting with auto-fix"
18
+ @echo " typecheck - Run type checking with mypy"
19
+ @echo " clean - Clean test artifacts"
20
+
21
+ # Run all tests
22
+ test:
23
+ uv run python3 -m pytest tests/
24
+
25
+ # Run only unit tests
26
+ test-unit:
27
+ uv run python3 -m pytest tests/unit/ -m "unit" --no-cov
28
+
29
+ # Run single unit test by pattern
30
+ test-unit-single:
31
+ @if [ -z "$(PATTERN)" ]; then echo "Usage: make test-unit-single PATTERN=test_name_pattern"; exit 1; fi
32
+ LOG_LEVEL=DEBUG uv run python3 -m pytest tests/unit/ -m "unit" --no-cov -k "$(PATTERN)" -v
33
+
34
+ # Run only integration tests
35
+ test-integration:
36
+ uv run python3 -m pytest tests/integration/ -m "integration"
37
+
38
+ # Run fast tests (exclude slow ones)
39
+ test-fast:
40
+ uv run python3 -m pytest tests/ -m "not slow"
41
+
42
+ # Run tests in watch mode (requires pytest-watch)
43
+ test-watch:
44
+ uv run pytest-watch --clear
45
+
46
+ # Run tests with coverage
47
+ test-cov:
48
+ uv run python3 -m pytest --cov=siili_ai_sdk --cov-report=term-missing
49
+
50
+ # Run tests with HTML coverage report
51
+ test-html:
52
+ uv run python3 -m pytest --cov=siili_ai_sdk --cov-report=html
53
+ @echo "Coverage report generated in htmlcov/index.html"
54
+
55
+ # Run specific test file
56
+ test-file:
57
+ @if [ -z "$(FILE)" ]; then echo "Usage: make test-file FILE=path/to/test_file.py"; exit 1; fi
58
+ uv run python3 -m pytest $(FILE) -v
59
+
60
+ # Run tests matching a pattern
61
+ test-pattern:
62
+ @if [ -z "$(PATTERN)" ]; then echo "Usage: make test-pattern PATTERN=test_name_pattern"; exit 1; fi
63
+ uv run python3 -m pytest -k "$(PATTERN)" -v
64
+
65
+ # Run linting checks
66
+ lint:
67
+ uv run ruff check .
68
+
69
+ # Run linting with auto-fix
70
+ lint-fix:
71
+ uv run ruff check --fix --unsafe-fixes .
72
+ uv run ruff format .
73
+
74
+ # Run type checking
75
+ typecheck:
76
+ uv run ty check siili_ai_sdk tests
77
+
78
+ # Clean test artifacts
79
+ clean:
80
+ rm -rf .pytest_cache/
81
+ rm -rf htmlcov/
82
+ rm -rf .coverage
83
+ find . -type d -name __pycache__ -exec rm -rf {} +
84
+ find . -type f -name "*.pyc" -delete
85
+
86
+ # Debug tests (run with verbose output and no capture)
87
+ test-debug:
88
+ uv run python3 -m pytest tests/ -v -s --tb=long
89
+
90
+ # Run tests and generate JUnit XML (for CI)
91
+ test-ci:
92
+ uv run python3 -m pytest tests/ --junitxml=test-results.xml --cov=siili_ai_sdk --cov-report=xml
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: siili-ai-sdk
3
+ Version: 0.5.0
4
+ Summary: Python SDK for building AI agents with multi-LLM support, streaming, and production-ready infrastructure
5
+ Project-URL: Homepage, https://github.com/siilisolutions/siili-ai-sdk
6
+ Project-URL: Repository, https://github.com/siilisolutions/siili-ai-sdk
7
+ Project-URL: Documentation, https://github.com/siilisolutions/siili-ai-sdk#readme
8
+ Author-email: Siili Solutions Oyj <info@siili.com>
9
+ License-Expression: MIT
10
+ Keywords: agents,ai,anthropic,claude,gpt,langchain,llm,openai,streaming
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: aioconsole>=0.8.1
21
+ Requires-Dist: azure-storage-blob
22
+ Requires-Dist: crawl4ai>=0.7.4
23
+ Requires-Dist: cryptography>=41.0.0
24
+ Requires-Dist: dotenv>=0.9.9
25
+ Requires-Dist: fastapi>=0.115.12
26
+ Requires-Dist: httpx>=0.25.0
27
+ Requires-Dist: langchain-anthropic>=1.3.0
28
+ Requires-Dist: langchain-core>=1.2.0
29
+ Requires-Dist: langchain-google-genai>=4.0.0
30
+ Requires-Dist: langchain-mcp-adapters>=0.2.1
31
+ Requires-Dist: langchain-ollama>=0.3.0
32
+ Requires-Dist: langchain-openai>=1.1.0
33
+ Requires-Dist: langchain-tavily>=0.2.15
34
+ Requires-Dist: langchain>=1.2.0
35
+ Requires-Dist: langgraph>=1.0.0
36
+ Requires-Dist: mcp>=1.9.2
37
+ Requires-Dist: pandas-stubs
38
+ Requires-Dist: pandas>=2.0.3
39
+ Requires-Dist: pyjwt>=2.8.0
40
+ Requires-Dist: pytest-asyncio>=0.21.1
41
+ Requires-Dist: pytest-cov>=4.1.0
42
+ Requires-Dist: pytest-mock>=3.11.1
43
+ Requires-Dist: pytest>=7.4.0
44
+ Requires-Dist: requests>=2.31.0
45
+ Requires-Dist: restrictedpython>=8.0
46
+ Requires-Dist: rich>=14.0.0
47
+ Requires-Dist: uvicorn>=0.33.0
48
+ Provides-Extra: dev
49
+ Requires-Dist: black; extra == 'dev'
50
+ Requires-Dist: mypy; extra == 'dev'
51
+ Requires-Dist: ruff; extra == 'dev'
52
+ Description-Content-Type: text/markdown
53
+
54
+ # Siili AI SDK
55
+
56
+ A Python SDK for building AI agents with multi-LLM support, streaming capabilities, and production-ready infrastructure.
57
+
58
+ ## Features
59
+
60
+ - **Multi-LLM Support**: OpenAI, Anthropic, Google, Azure models
61
+ - **Streaming**: Real-time response streaming
62
+ - **Tools**: Custom tool integration with LangChain
63
+ - **Production Ready**: FastAPI server with REST/SSE APIs
64
+ - **Type Safe**: Full type annotations
65
+
66
+ ## Quick Start
67
+
68
+ ### Simple Agent
69
+
70
+ ```python
71
+ from dotenv import load_dotenv
72
+ from siili_ai_sdk.agent.base_agent import BaseAgent
73
+
74
+ class HelloAgent(BaseAgent):
75
+ def __init__(self):
76
+ super().__init__(system_prompt="You're an unhelpful assistant that cant resist constantly talking about cats.")
77
+
78
+ if __name__ == "__main__":
79
+ load_dotenv()
80
+ agent = HelloAgent()
81
+ print(agent.get_response_text("Hello"))
82
+ ```
83
+
84
+ ### Agent with Tools + FastAPI Server
85
+
86
+ ```python
87
+ from typing import List
88
+ import uvicorn
89
+ from dotenv import load_dotenv
90
+ from fastapi import FastAPI
91
+ from fastapi.middleware.cors import CORSMiddleware
92
+
93
+ from siili_ai_sdk.agent.base_agent import BaseAgent
94
+ from siili_ai_sdk.tools.tool_provider import ToolProvider, tool, BaseTool
95
+ from siili_ai_sdk.server.api.routers.api_builder import ApiBuilder
96
+ from siili_ai_sdk.models.model_registry import ModelRegistry
97
+
98
+ load_dotenv()
99
+
100
+ app = FastAPI(title="Agent SDK Backend Example", version="0.0.1")
101
+
102
+ app.add_middleware(
103
+ CORSMiddleware,
104
+ allow_origins=["*"],
105
+ allow_credentials=True,
106
+ allow_methods=["*"],
107
+ allow_headers=["*"],
108
+ )
109
+
110
+ class DemoTool(ToolProvider):
111
+ def get_tools(self) -> List[BaseTool]:
112
+ @tool
113
+ def get_secret_greeting() -> str:
114
+ """Returns the users secret greeting."""
115
+ return "kikkelis kokkelis"
116
+
117
+ @tool
118
+ def get_user_name() -> str:
119
+ """Returns the users name."""
120
+ return "Seppo Hovi"
121
+
122
+ return [get_secret_greeting, get_user_name]
123
+
124
+ class DemoAgent(BaseAgent):
125
+ def get_tool_providers(self) -> List[ToolProvider]:
126
+ return [DemoTool()]
127
+
128
+ @app.on_event("startup")
129
+ async def startup_event():
130
+ agent = DemoAgent(llm_model=ModelRegistry.CLAUDE_4_SONNET)
131
+ api_builder = ApiBuilder.local(agent=agent)
132
+ thread_router = api_builder.build_thread_router()
133
+ app.include_router(thread_router)
134
+
135
+ def run_server():
136
+ uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True, log_level="info")
137
+
138
+ if __name__ == "__main__":
139
+ run_server()
140
+ ```
141
+
142
+ ## Configuration
143
+
144
+ Set up your environment variables:
145
+
146
+ ```bash
147
+ # API Keys
148
+ ANTHROPIC_API_KEY=your-anthropic-key
149
+ OPENAI_API_KEY=your-openai-key
150
+ GOOGLE_API_KEY=your-google-key
151
+
152
+ # Azure (optional)
153
+ AZURE_API_KEY=your-azure-key
154
+ AZURE_ENDPOINT=https://your-resource.openai.azure.com/
155
+ ```
156
+
157
+ ## Available Models
158
+
159
+ ```python
160
+ from siili_ai_sdk.models.model_registry import ModelRegistry
161
+
162
+ # Use model registry for easy access
163
+ ModelRegistry.CLAUDE_4_SONNET
164
+ ModelRegistry.GPT_4_1
165
+ ModelRegistry.GEMINI_2_5_FLASH
166
+ ModelRegistry.O4_MINI
167
+
168
+ # Or use aliases
169
+ ModelRegistry.from_name("sonnet") # -> CLAUDE_4_SONNET
170
+ ModelRegistry.from_name("gpt 4.1") # -> GPT_4_1
171
+ ```
172
+
173
+ ## More Usage Examples
174
+
175
+ ### Streaming Response
176
+
177
+ ```python
178
+ async def stream_example():
179
+ agent = DemoAgent()
180
+ async for chunk in agent.get_response_stream("Write a story"):
181
+ print(chunk.content, end="", flush=True)
182
+ ```
183
+
184
+ ### Structured Response
185
+
186
+ ```python
187
+ from pydantic import BaseModel
188
+
189
+ class Recipe(BaseModel):
190
+ name: str
191
+ ingredients: list[str]
192
+ instructions: list[str]
193
+
194
+ response = agent.get_structured_response("Create a pasta recipe", Recipe)
195
+ print(f"Recipe: {response.name}")
196
+ ```
197
+
198
+ ### Interactive CLI
199
+
200
+ ```python
201
+ agent = DemoAgent()
202
+ agent.run_cli() # Starts interactive chat
203
+ ```
204
+
205
+ ## API Endpoints
206
+
207
+ When running the FastAPI server:
208
+
209
+ ```bash
210
+ # Health check
211
+ GET /health
212
+
213
+ # Create thread
214
+ POST /threads
215
+
216
+ # Send message (streaming)
217
+ POST /threads/{thread_id}/messages/stream
218
+
219
+ # Get messages
220
+ GET /threads/{thread_id}/messages
221
+ ```
222
+
223
+ ## Development
224
+
225
+ ```bash
226
+ # Setup
227
+ ./setup.sh
228
+
229
+ # Run tests
230
+ make test
231
+
232
+ # Format code
233
+ ruff check --fix
234
+ ruff format
235
+ ```
236
+
237
+ ## Project Structure
238
+
239
+ ```
240
+ siili_ai_sdk/
241
+ ├── agent/ # Core agent implementations
242
+ ├── llm/ # LangChain service and streaming
243
+ ├── models/ # LLM providers and configuration
244
+ ├── thread/ # Conversation management
245
+ ├── tools/ # Tool system
246
+ ├── server/ # FastAPI server infrastructure
247
+ └── utils/ # Shared utilities
248
+ ```
249
+