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.
- siili_ai_sdk-0.5.0/.cursor/rules/global.mdc +32 -0
- siili_ai_sdk-0.5.0/.cursor/rules/post_run.mdc +14 -0
- siili_ai_sdk-0.5.0/.cursor/rules/repo_overview.mdc +84 -0
- siili_ai_sdk-0.5.0/.cursor/rules/testing-structure.mdc +54 -0
- siili_ai_sdk-0.5.0/.gitignore +41 -0
- siili_ai_sdk-0.5.0/Makefile +92 -0
- siili_ai_sdk-0.5.0/PKG-INFO +249 -0
- siili_ai_sdk-0.5.0/README.md +196 -0
- siili_ai_sdk-0.5.0/__init__.py.bak +20 -0
- siili_ai_sdk-0.5.0/env.example +28 -0
- siili_ai_sdk-0.5.0/kill.sh +39 -0
- siili_ai_sdk-0.5.0/py.typed +1 -0
- siili_ai_sdk-0.5.0/pyproject.toml +147 -0
- siili_ai_sdk-0.5.0/setup.sh +11 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/__init__.py +21 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/agent/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/agent/base_agent.py +205 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/__init__.py +22 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/builder.py +61 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/file_storage_provider.py +27 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/mime_types.py +118 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/models.py +63 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/provider_support.py +53 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/base_file_storage.py +32 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/impl/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/attachments/storage/impl/local_file_storage.py +101 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/config/credentials_provider.py +10 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/config/env.py +55 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/config/env_credentials_provider.py +7 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/config/get_credentials_provider.py +14 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/__init__.py +9 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/image_generator.py +83 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/options.py +24 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/providers/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/providers/google.py +75 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/image_gen/providers/openai.py +60 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cancellation_handle.py +10 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/consumption_estimate.py +26 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/consumption_estimate_builder.py +113 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/consumption_extractor.py +59 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/consumption/token_usage.py +31 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/converters.py +146 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/builtin_cost_provider.py +83 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/cost_estimate.py +8 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/cost/cost_provider.py +28 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/extract_error_message.py +37 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/langchain_loop_manager.py +270 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/langchain_service.py +195 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/message_handler.py +188 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/block_manager.py +152 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/models.py +42 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/streaming_content_handler.py +157 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/streaming_event_handler.py +215 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/llm/streaming/streaming_state_manager.py +58 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/anthropic_factory.py +33 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/base_model_factory.py +71 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/google_factory.py +30 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/ollama_factory.py +41 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/factories/openai_factory.py +50 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_config.py +46 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_families.py +7 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_model.py +17 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/llm_wrapper.py +25 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/model_registry.py +156 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/anthropic_provider.py +29 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/azure_provider.py +31 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/base_provider.py +62 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/google_provider.py +26 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/ollama_provider.py +26 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/openai_provider.py +26 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/models/providers/provider_type.py +90 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/get_prompt_loader.py +13 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/local_prompt_loader.py +21 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/prompt_loader.py +48 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/prompt/prompt_loader_mode.py +14 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/py.typed +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/base_playback.py +90 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/base_recorder.py +50 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/conditional_recorder.py +38 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/impl/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/impl/local_playback.py +76 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/impl/local_recorder.py +85 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/recording/langchain_serializer.py +88 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/api_builder.py +126 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/file_router_factory.py +111 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/routers/thread_router_factory.py +267 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/format_sse_event.py +41 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/negotiate_streaming_response.py +8 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/api/streaming/streaming_negotiator.py +10 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/base_authorizer.py +61 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/base_user.py +13 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/authorization/dummy_authorizer.py +17 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/job_processor/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/job_processor/base_job_processor.py +8 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/job_processor/thread_job_processor.py +32 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/cancellation_publisher.py +7 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/cancellation_subscriber.py +37 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/event_publisher.py +13 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/impl/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/impl/local_cancellation_pubsub.py +48 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/pubsub/impl/signalr_publisher.py +36 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/agent_job_queue.py +27 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/impl/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/queue/impl/azure_queue.py +24 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/agent_response_generator.py +39 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/response_generator.py +13 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/response/simple_agent_response_generator.py +14 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/thread_converters.py +113 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/thread_models.py +90 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/services/thread_service.py +91 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/__init__.py +1 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/base_thread_repository.py +51 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/impl/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/impl/in_memory_thread_repository.py +100 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/impl/local_file_thread_repository.py +217 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/thread_filter.py +166 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/server/storage/thread_metadata.py +53 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/block_display.py +92 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/display_manager.py +84 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/cli/live_cli.py +235 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/event_adapter.py +28 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/streaming_block_adapter.py +57 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/adapters/sync_adapter.py +76 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/models.py +224 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/thread/thread_container.py +467 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tools/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/crawl_tool_provider.py +19 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/mcp_tool_provider.py +93 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tools/impl/search_tool_provider.py +18 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tools/tool_provider.py +131 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tracing/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/tracing/agent_trace.py +79 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/utils/__init__.py +0 -0
- siili_ai_sdk-0.5.0/siili_ai_sdk/utils/init_logger.py +24 -0
- siili_ai_sdk-0.5.0/tests/__init__.py +0 -0
- siili_ai_sdk-0.5.0/tests/conftest.py +0 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_consumption_tracking/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_event_stream_basic/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-3-7-sonnet-latest/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-haiku-4-5-20251001/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-opus-4-5-20251101/1.jsonl +32 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-sonnet-4-20250514/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_claude-sonnet-4-5-20250929/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gemini-2.5-flash/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gemini-3-flash-preview/1.jsonl +19 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gemini-3-pro-preview/1.jsonl +20 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gpt-4.1/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gpt-5.1/1.jsonl +31 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_gpt-5.2/1.jsonl +30 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_o4-mini/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_text_with_cancellation/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-3-7-sonnet-latest/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-haiku-4-5-20251001/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-opus-4-1-20250805/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-opus-4-5-20251101/1.jsonl +53 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-sonnet-4-20250514/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_claude-sonnet-4-5-20250929/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gemini-2.5-flash/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gemini-3-flash-preview/1.jsonl +44 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-4.1/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.1/1.jsonl +142 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.1-codex/1.jsonl +64 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.2/1.jsonl +58 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_gpt-5.2-pro/1.jsonl +46 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_response_with_tool_call_o4-mini/1.jsonl +16 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_get_structured_response/1.json +4 -0
- siili_ai_sdk-0.5.0/tests/data/recordings/test_mystery_streaming_issue/1.jsonl +6 -0
- siili_ai_sdk-0.5.0/tests/integration/__init__.py +0 -0
- siili_ai_sdk-0.5.0/tests/integration/test_cost_tracking_integration.py +79 -0
- siili_ai_sdk-0.5.0/tests/integration/test_mcp_tool_provider.py +68 -0
- siili_ai_sdk-0.5.0/tests/manual/__init__.py +0 -0
- siili_ai_sdk-0.5.0/tests/manual/test_crawl.py +22 -0
- siili_ai_sdk-0.5.0/tests/manual/test_search.py +22 -0
- siili_ai_sdk-0.5.0/tests/unit/__init__.py +0 -0
- siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/agent/test_base_agent.py +277 -0
- siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/llm/streaming/test_streaming_event_handler.py +221 -0
- siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/models/__init__.py +0 -0
- siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/models/test_model_registry.py +76 -0
- siili_ai_sdk-0.5.0/tests/unit/siili_ai_sdk/tools/impl/__init__.py +0 -0
- 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
|
+
|