synapsekit 1.4.0__tar.gz → 1.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.all-contributorsrc +7 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/CHANGELOG.md +35 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/PKG-INFO +23 -1
- {synapsekit-1.4.0 → synapsekit-1.4.2}/README.md +1 -0
- synapsekit-1.4.2/examples/README.md +70 -0
- synapsekit-1.4.2/examples/agent_tools.py +95 -0
- synapsekit-1.4.2/examples/caching_retries.py +171 -0
- synapsekit-1.4.2/examples/graph_workflow.py +125 -0
- synapsekit-1.4.2/examples/multi_provider.py +132 -0
- synapsekit-1.4.2/examples/rag_quickstart.py +56 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/pyproject.toml +17 -3
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/__init__.py +20 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/__init__.py +6 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/__init__.py +6 -0
- synapsekit-1.4.2/src/synapsekit/agents/tools/bing_search.py +105 -0
- synapsekit-1.4.2/src/synapsekit/agents/tools/google_search.py +84 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/sql_query.py +24 -12
- synapsekit-1.4.2/src/synapsekit/agents/tools/wolfram.py +96 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/compiled.py +65 -2
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/graph.py +15 -1
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/__init__.py +12 -0
- synapsekit-1.4.2/src/synapsekit/llm/_cache_dynamodb.py +105 -0
- synapsekit-1.4.2/src/synapsekit/llm/_cache_memcached.py +107 -0
- synapsekit-1.4.2/src/synapsekit/llm/aleph_alpha.py +81 -0
- synapsekit-1.4.2/src/synapsekit/llm/huggingface.py +80 -0
- synapsekit-1.4.2/src/synapsekit/llm/minimax.py +110 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/__init__.py +5 -1
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/directory.py +2 -1
- synapsekit-1.4.2/src/synapsekit/loaders/yaml_loader.py +42 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/rag/facade.py +13 -1
- synapsekit-1.4.2/tests/agents/test_bing_search.py +155 -0
- synapsekit-1.4.2/tests/agents/test_wolfram_alpha.py +81 -0
- synapsekit-1.4.2/tests/agents/tools/test_google_search.py +88 -0
- synapsekit-1.4.2/tests/agents/tools/test_sql_query.py +92 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_checkpointing.py +56 -0
- synapsekit-1.4.2/tests/llm/test_cache_dynamodb.py +81 -0
- synapsekit-1.4.2/tests/llm/test_cache_memcached.py +74 -0
- synapsekit-1.4.2/tests/llm/test_huggingface.py +78 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_providers.py +105 -0
- synapsekit-1.4.2/tests/loaders/test_yaml_loader.py +73 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/profile/README.md +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/workflows/ci.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/workflows/publish.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.github/workflows/welcome.yml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.gitignore +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/.pre-commit-config.yaml +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/CODE_OF_CONDUCT.md +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/CONTRIBUTING.md +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/LICENSE +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/Makefile +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/SECURITY.md +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/assets/banner.svg +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/assets/favicon.svg +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/assets/logo.svg +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/_api.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/_compat.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/a2a/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/a2a/agent_card.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/a2a/client.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/a2a/server.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/a2a/types.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/executor.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/function_calling.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/guardrails.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/memory.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/multi/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/multi/crew.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/multi/handoff.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/multi/supervisor.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/pii_redactor.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/react.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/registry.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/step_events.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tool_decorator.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/api_builder.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/arxiv_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/aws_lambda.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/brave_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/calculator.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/datetime_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/duck_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/email_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/file_list.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/file_read.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/file_write.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/github_api.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/google_calendar.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/graphql.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/http_request.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/human_input.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/image_analysis.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/jira.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/json_query.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/pdf_reader.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/pubmed_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/python_repl.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/regex_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/sentiment.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/shell.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/slack.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/speech_to_text.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/sql_schema.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/summarization.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/tavily_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/text_to_speech.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/translation.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/vector_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/web_scraper.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/web_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/wikipedia.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/agents/tools/youtube_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/cli/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/cli/main.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/cli/serve.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/cli/test.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/embeddings/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/embeddings/backend.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/decorators.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/faithfulness.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/groundedness.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/pipeline.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/regression.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/evaluation/relevancy.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/approval.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/json_file.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/memory.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/postgres.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/redis.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/checkpointers/sqlite.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/dynamic_route.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/edge.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/errors.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/fan_out.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/interrupt.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/mermaid.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/node.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/state.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/streaming.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/subgraph.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/trace.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/graph/visualization.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_cache.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_filesystem_cache.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_rate_limit.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_redis_cache.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_retry.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_semantic_cache.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/_sqlite_cache.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/ai21.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/anthropic.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/azure_openai.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/bedrock.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/cerebras.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/cloudflare.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/cohere.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/cost_router.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/databricks.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/deepseek.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/ernie.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/fallback_chain.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/fireworks.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/gemini.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/groq.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/llamacpp.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/mistral.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/moonshot.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/multimodal.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/ollama.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/openai.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/openrouter.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/perplexity.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/structured.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/together.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/vertex_ai.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/llm/zhipu.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/audio.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/csv.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/docx.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/excel.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/html.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/image.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/json_loader.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/markdown.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/pdf.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/pptx.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/text.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/video.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/loaders/web.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/mcp/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/mcp/client.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/mcp/server.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/buffer.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/conversation.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/entity.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/hybrid.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/redis.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/sqlite.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/summary_buffer.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/memory/token_buffer.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/audit_log.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/budget_guard.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/cost_tracker.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/distributed.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/otel.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/tracer.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/observability/ui.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/parsers/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/parsers/json_parser.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/parsers/list_parser.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/parsers/pydantic_parser.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/plugins.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/prompts/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/prompts/hub.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/prompts/template.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/py.typed +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/rag/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/rag/pipeline.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/adaptive.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/chroma.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/cohere_reranker.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/contextual.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/contextual_compression.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/crag.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/cross_encoder.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/ensemble.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/faiss.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/flare.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/graphrag.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/hybrid_search.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/hyde.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/multi_step.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/parent_document.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/pinecone.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/qdrant.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/query_decomposition.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/rag_fusion.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/retriever.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/self_query.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/self_rag.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/sentence_window.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/step_back.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/retrieval/vectorstore.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/base.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/character.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/markdown.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/recursive.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/semantic.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/src/synapsekit/text_splitters/token.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_api_builder_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_aws_lambda_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_executor.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_function_calling.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_google_calendar_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_memory.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_pii_redactor.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_react.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_shell_tool.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_sql_schema.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_streaming_steps.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_tool_decorator.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_tools.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/agents/test_web_scraper.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/conftest.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_build.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_cycles.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_json_checkpointer.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_mermaid.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_run.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_state.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_stream.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/graph/test_visualization.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_cache_retry.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_filesystem_cache.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_function_calling_providers.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_llamacpp.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_llm.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_new_providers_185.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/llm/test_vertex_ai.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/loaders/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/loaders/test_audio_video_loaders.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/loaders/test_docx_loader.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/loaders/test_loaders.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/loaders/test_markdown_loader.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/memory/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/memory/test_memory.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/memory/test_redis_memory.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/observability/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/observability/test_audit_log.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/observability/test_tracer.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/parsers/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/parsers/test_parsers.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/prompts/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/prompts/test_prompts.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/rag/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/rag/test_facade.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/rag/test_pipeline.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/retrieval/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/retrieval/test_backends.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/retrieval/test_graphrag.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/retrieval/test_hyde.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/retrieval/test_retriever.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/retrieval/test_vectorstore.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v051_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v052_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v053_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v060_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v061_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v062_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v063_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v065_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v066_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v068_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v069_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v070_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v080_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v090_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v100_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v120_features.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v120_integration.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v130_eval_regression.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/test_v130_routing.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/text_splitters/__init__.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/text_splitters/test_markdown.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/tests/text_splitters/test_splitters.py +0 -0
- {synapsekit-1.4.0 → synapsekit-1.4.2}/uv.lock +0 -0
|
@@ -49,6 +49,13 @@
|
|
|
49
49
|
"avatar_url": "https://avatars.githubusercontent.com/u/136477030?v=4",
|
|
50
50
|
"profile": "https://github.com/DhruvGarg111",
|
|
51
51
|
"contributions": ["code"]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"login": "adaumsilva",
|
|
55
|
+
"name": "Adam Silva",
|
|
56
|
+
"avatar_url": "https://avatars.githubusercontent.com/u/178027480?v=4",
|
|
57
|
+
"profile": "https://github.com/adaumsilva",
|
|
58
|
+
"contributions": ["code"]
|
|
52
59
|
}
|
|
53
60
|
],
|
|
54
61
|
"contributorsPerLine": 7
|
|
@@ -7,6 +7,41 @@ SynapseKit uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.4.2] — 2026-03-28
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **HuggingFaceLLM** — Hugging Face Inference API via `AsyncInferenceClient`; supports serverless API (model ID) and Dedicated Inference Endpoints (URL); streaming and generate
|
|
15
|
+
- **DynamoDBCacheBackend** — serverless LLM response caching on AWS DynamoDB; configurable partition key, TTL via `ttl_seconds`, custom region and endpoint
|
|
16
|
+
- **MemcachedCacheBackend** — high-throughput distributed LLM caching via `aiomcache`; TTL via `exptime`; async-native
|
|
17
|
+
- **GoogleSearchTool** — Google web search via SerpAPI (`google-search-results`); graceful handling of missing keys, empty results, and API errors
|
|
18
|
+
- **Graph versioning and checkpoint migration** — `StateGraph(version="1", migrations={...})`; `CompiledGraph.resume()` now applies migration chains when loading older checkpoint versions; supports direct and chained `(next_version, state_dict)` migrations; missing paths raise `GraphRuntimeError`
|
|
19
|
+
- 11 new tests (1368 total)
|
|
20
|
+
|
|
21
|
+
### Improved
|
|
22
|
+
|
|
23
|
+
- **SQLQueryTool** — added `params` dict for parameterized queries (eliminates string interpolation); `max_rows` cap; fixed variable name shadowing
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## [1.4.1] — 2026-03-27
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **MinimaxLLM provider** — `MinimaxLLM` for Minimax API with SSE streaming; requires `group_id`; auto-detected from `minimax-*` model prefix
|
|
32
|
+
- **AlephAlphaLLM provider** — `AlephAlphaLLM` for Aleph Alpha Luminous and Pharia models; httpx-based streaming; auto-detected from `luminous-*`/`pharia-*` prefixes
|
|
33
|
+
- **YAMLLoader** — load YAML files (list-of-objects or single-object) into `Document` list; configurable `text_key` and `metadata_keys`; uses `yaml.safe_load()`
|
|
34
|
+
- **BingSearchTool** — web search via Bing Web Search API v7; auth via `Ocp-Apim-Subscription-Key`; supports `query`, `count` (capped at 50), `market`
|
|
35
|
+
- **WolframAlphaTool** — computational queries via Wolfram Alpha API; short-answer endpoint; thread-executor async wrapper
|
|
36
|
+
- **Usage examples** — `examples/` directory with 5 runnable scripts: RAG quickstart, agent with tools, graph workflow, multi-provider, caching & retries
|
|
37
|
+
- 30 new tests (1357 total)
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Added missing return type annotations to `_loader_for()` in `loaders/directory.py` and `__getattr__()` in `loaders/__init__.py`
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
10
45
|
## [1.4.0] — 2026-03-25
|
|
11
46
|
|
|
12
47
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synapsekit
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: Async-native Python framework for building production-grade LLM applications. Streaming-first, 2 dependencies, fully transparent.
|
|
5
5
|
Project-URL: Homepage, https://github.com/SynapseKit/SynapseKit
|
|
6
6
|
Project-URL: Repository, https://github.com/SynapseKit/SynapseKit
|
|
@@ -23,8 +23,11 @@ Requires-Dist: numpy>=1.26
|
|
|
23
23
|
Requires-Dist: rank-bm25>=0.2.2
|
|
24
24
|
Provides-Extra: ai21
|
|
25
25
|
Requires-Dist: ai21>=2.0; extra == 'ai21'
|
|
26
|
+
Provides-Extra: aleph-alpha
|
|
27
|
+
Requires-Dist: aleph-alpha-client>=7.0; extra == 'aleph-alpha'
|
|
26
28
|
Provides-Extra: all
|
|
27
29
|
Requires-Dist: ai21>=2.0; extra == 'all'
|
|
30
|
+
Requires-Dist: aiomcache>=0.8; extra == 'all'
|
|
28
31
|
Requires-Dist: anthropic>=0.25; extra == 'all'
|
|
29
32
|
Requires-Dist: beautifulsoup4>=4.12; extra == 'all'
|
|
30
33
|
Requires-Dist: boto3>=1.34; extra == 'all'
|
|
@@ -36,8 +39,10 @@ Requires-Dist: faiss-cpu>=1.7; extra == 'all'
|
|
|
36
39
|
Requires-Dist: fastapi>=0.110; extra == 'all'
|
|
37
40
|
Requires-Dist: google-cloud-aiplatform>=1.38; extra == 'all'
|
|
38
41
|
Requires-Dist: google-generativeai>=0.7; extra == 'all'
|
|
42
|
+
Requires-Dist: google-search-results>=2.4; extra == 'all'
|
|
39
43
|
Requires-Dist: groq>=0.9; extra == 'all'
|
|
40
44
|
Requires-Dist: httpx>=0.27; extra == 'all'
|
|
45
|
+
Requires-Dist: huggingface-hub>=0.20; extra == 'all'
|
|
41
46
|
Requires-Dist: llama-cpp-python>=0.2; extra == 'all'
|
|
42
47
|
Requires-Dist: lxml>=5.0; extra == 'all'
|
|
43
48
|
Requires-Dist: mcp>=1.0; extra == 'all'
|
|
@@ -47,11 +52,13 @@ Requires-Dist: openai>=1.0; extra == 'all'
|
|
|
47
52
|
Requires-Dist: pinecone>=3.0; extra == 'all'
|
|
48
53
|
Requires-Dist: psycopg[binary]>=3.1; extra == 'all'
|
|
49
54
|
Requires-Dist: pypdf>=4.0; extra == 'all'
|
|
55
|
+
Requires-Dist: pyyaml>=6.0; extra == 'all'
|
|
50
56
|
Requires-Dist: qdrant-client>=1.9; extra == 'all'
|
|
51
57
|
Requires-Dist: redis>=5.0; extra == 'all'
|
|
52
58
|
Requires-Dist: sentence-transformers>=2.7; extra == 'all'
|
|
53
59
|
Requires-Dist: tavily-python>=0.3; extra == 'all'
|
|
54
60
|
Requires-Dist: uvicorn[standard]>=0.29; extra == 'all'
|
|
61
|
+
Requires-Dist: wolframalpha>=5.0; extra == 'all'
|
|
55
62
|
Requires-Dist: youtube-search-python>=1.6; extra == 'all'
|
|
56
63
|
Provides-Extra: anthropic
|
|
57
64
|
Requires-Dist: anthropic>=0.25; extra == 'anthropic'
|
|
@@ -69,6 +76,8 @@ Provides-Extra: cohere
|
|
|
69
76
|
Requires-Dist: cohere>=5.0; extra == 'cohere'
|
|
70
77
|
Provides-Extra: docx
|
|
71
78
|
Requires-Dist: python-docx>=1.0; extra == 'docx'
|
|
79
|
+
Provides-Extra: dynamodb
|
|
80
|
+
Requires-Dist: boto3>=1.34; extra == 'dynamodb'
|
|
72
81
|
Provides-Extra: ernie
|
|
73
82
|
Requires-Dist: erniebot>=0.5; extra == 'ernie'
|
|
74
83
|
Provides-Extra: excel
|
|
@@ -79,6 +88,8 @@ Provides-Extra: gcal-tool
|
|
|
79
88
|
Requires-Dist: google-api-python-client>=2.0; extra == 'gcal-tool'
|
|
80
89
|
Provides-Extra: gemini
|
|
81
90
|
Requires-Dist: google-generativeai>=0.7; extra == 'gemini'
|
|
91
|
+
Provides-Extra: google-search
|
|
92
|
+
Requires-Dist: google-search-results>=2.4; extra == 'google-search'
|
|
82
93
|
Provides-Extra: groq
|
|
83
94
|
Requires-Dist: groq>=0.9; extra == 'groq'
|
|
84
95
|
Provides-Extra: html
|
|
@@ -86,10 +97,16 @@ Requires-Dist: beautifulsoup4>=4.12; extra == 'html'
|
|
|
86
97
|
Requires-Dist: lxml>=5.0; extra == 'html'
|
|
87
98
|
Provides-Extra: http
|
|
88
99
|
Requires-Dist: aiohttp>=3.9; extra == 'http'
|
|
100
|
+
Provides-Extra: huggingface
|
|
101
|
+
Requires-Dist: huggingface-hub>=0.20; extra == 'huggingface'
|
|
89
102
|
Provides-Extra: llamacpp
|
|
90
103
|
Requires-Dist: llama-cpp-python>=0.2; extra == 'llamacpp'
|
|
91
104
|
Provides-Extra: mcp
|
|
92
105
|
Requires-Dist: mcp>=1.0; extra == 'mcp'
|
|
106
|
+
Provides-Extra: memcached
|
|
107
|
+
Requires-Dist: aiomcache>=0.8; extra == 'memcached'
|
|
108
|
+
Provides-Extra: minimax
|
|
109
|
+
Requires-Dist: httpx>=0.27; extra == 'minimax'
|
|
93
110
|
Provides-Extra: mistral
|
|
94
111
|
Requires-Dist: mistralai>=1.0; extra == 'mistral'
|
|
95
112
|
Provides-Extra: ollama
|
|
@@ -124,6 +141,10 @@ Requires-Dist: openai>=1.0; extra == 'video'
|
|
|
124
141
|
Provides-Extra: web
|
|
125
142
|
Requires-Dist: beautifulsoup4>=4.12; extra == 'web'
|
|
126
143
|
Requires-Dist: httpx>=0.27; extra == 'web'
|
|
144
|
+
Provides-Extra: wolfram
|
|
145
|
+
Requires-Dist: wolframalpha>=5.0; extra == 'wolfram'
|
|
146
|
+
Provides-Extra: yaml
|
|
147
|
+
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
|
|
127
148
|
Provides-Extra: youtube
|
|
128
149
|
Requires-Dist: youtube-search-python>=1.6; extra == 'youtube'
|
|
129
150
|
Description-Content-Type: text/markdown
|
|
@@ -334,6 +355,7 @@ Read [CONTRIBUTING.md](CONTRIBUTING.md) to get started. Look for issues tagged [
|
|
|
334
355
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Arjunkundapur"><img src="https://avatars.githubusercontent.com/u/64265396?v=4" width="100px;" alt="Arjun Kundapur"/><br /><sub><b>Arjun Kundapur</b></sub></a><br /><a href="https://github.com/SynapseKit/SynapseKit/commits?author=Arjunkundapur" title="Code">💻</a></td>
|
|
335
356
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ashusf90"><img src="https://avatars.githubusercontent.com/u/153393197?v=4" width="100px;" alt="Harshit Gupta"/><br /><sub><b>Harshit Gupta</b></sub></a><br /><a href="https://github.com/SynapseKit/synapsekit-docs/pull/34" title="Documentation">📖</a></td>
|
|
336
357
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DhruvGarg111"><img src="https://avatars.githubusercontent.com/u/136477030?v=4" width="100px;" alt="Dhruv Garg"/><br /><sub><b>Dhruv Garg</b></sub></a><br /><a href="https://github.com/SynapseKit/SynapseKit/commits?author=DhruvGarg111" title="Code">💻</a></td>
|
|
358
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/adaumsilva"><img src="https://avatars.githubusercontent.com/u/178027480?v=4" width="100px;" alt="Adam Silva"/><br /><sub><b>Adam Silva</b></sub></a><br /><a href="https://github.com/SynapseKit/SynapseKit/commits?author=adaumsilva" title="Code">💻</a></td>
|
|
337
359
|
</tr>
|
|
338
360
|
</tbody>
|
|
339
361
|
</table>
|
|
@@ -204,6 +204,7 @@ Read [CONTRIBUTING.md](CONTRIBUTING.md) to get started. Look for issues tagged [
|
|
|
204
204
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Arjunkundapur"><img src="https://avatars.githubusercontent.com/u/64265396?v=4" width="100px;" alt="Arjun Kundapur"/><br /><sub><b>Arjun Kundapur</b></sub></a><br /><a href="https://github.com/SynapseKit/SynapseKit/commits?author=Arjunkundapur" title="Code">💻</a></td>
|
|
205
205
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ashusf90"><img src="https://avatars.githubusercontent.com/u/153393197?v=4" width="100px;" alt="Harshit Gupta"/><br /><sub><b>Harshit Gupta</b></sub></a><br /><a href="https://github.com/SynapseKit/synapsekit-docs/pull/34" title="Documentation">📖</a></td>
|
|
206
206
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DhruvGarg111"><img src="https://avatars.githubusercontent.com/u/136477030?v=4" width="100px;" alt="Dhruv Garg"/><br /><sub><b>Dhruv Garg</b></sub></a><br /><a href="https://github.com/SynapseKit/SynapseKit/commits?author=DhruvGarg111" title="Code">💻</a></td>
|
|
207
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/adaumsilva"><img src="https://avatars.githubusercontent.com/u/178027480?v=4" width="100px;" alt="Adam Silva"/><br /><sub><b>Adam Silva</b></sub></a><br /><a href="https://github.com/SynapseKit/SynapseKit/commits?author=adaumsilva" title="Code">💻</a></td>
|
|
207
208
|
</tr>
|
|
208
209
|
</tbody>
|
|
209
210
|
</table>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
This directory contains runnable examples demonstrating key SynapseKit features.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Install SynapseKit with OpenAI support:
|
|
8
|
+
```bash
|
|
9
|
+
pip install synapsekit[openai]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Set your API key:
|
|
13
|
+
```bash
|
|
14
|
+
export OPENAI_API_KEY=sk-...
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
### 1. `rag_quickstart.py` — RAG Basics
|
|
20
|
+
The simplest way to get started: load text, add documents, and query with streaming.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python examples/rag_quickstart.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. `agent_tools.py` — ReAct Agent with Tools
|
|
27
|
+
Create a ReAct agent with built-in and custom tools. Shows reasoning and tool execution.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
python examples/agent_tools.py
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 3. `graph_workflow.py` — State Graph with Conditional Routing
|
|
34
|
+
Build workflows with state management, conditional edges, and visualization.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python examples/graph_workflow.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 4. `multi_provider.py` — Multi-Provider Comparison
|
|
41
|
+
Run the same prompt across OpenAI, Anthropic, and Ollama to compare responses.
|
|
42
|
+
|
|
43
|
+
Requires additional setup:
|
|
44
|
+
```bash
|
|
45
|
+
pip install synapsekit[openai,anthropic]
|
|
46
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
python examples/multi_provider.py
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 5. `caching_retries.py` — Advanced LLM Configuration
|
|
54
|
+
Configure response caching, automatic retries, and cost tracking with budget limits.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
python examples/caching_retries.py
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## General Pattern
|
|
61
|
+
|
|
62
|
+
All examples follow this pattern:
|
|
63
|
+
- Use `os.environ` for API keys (never hardcode)
|
|
64
|
+
- Include docstrings explaining what the example does
|
|
65
|
+
- Work with minimal dependencies (`pip install synapsekit[openai]`)
|
|
66
|
+
- Print step-by-step progress for learning
|
|
67
|
+
|
|
68
|
+
## Contributing
|
|
69
|
+
|
|
70
|
+
Found an issue or want to add more examples? Open an issue or PR on GitHub!
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ReAct Agent with Custom Tools
|
|
3
|
+
==============================
|
|
4
|
+
|
|
5
|
+
This example shows how to create a ReAct agent with built-in and custom tools.
|
|
6
|
+
The agent can reason about which tool to use and execute them step-by-step.
|
|
7
|
+
|
|
8
|
+
Prerequisites:
|
|
9
|
+
pip install synapsekit[openai]
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
export OPENAI_API_KEY=sk-...
|
|
13
|
+
python examples/agent_tools.py
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import os
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
|
|
20
|
+
from synapsekit import ReActAgent, tool, CalculatorTool, DateTimeTool
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Define a custom tool
|
|
24
|
+
@tool
|
|
25
|
+
def get_weather(location: str) -> str:
|
|
26
|
+
"""
|
|
27
|
+
Get current weather for a location.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
location: City name or location
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Weather description
|
|
34
|
+
"""
|
|
35
|
+
# Mock weather data
|
|
36
|
+
return f"The weather in {location} is sunny with 22°C temperature."
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@tool
|
|
40
|
+
def convert_currency(amount: float, from_currency: str, to_currency: str) -> str:
|
|
41
|
+
"""
|
|
42
|
+
Convert currency from one type to another.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
amount: Amount to convert
|
|
46
|
+
from_currency: Source currency code (e.g., USD, EUR)
|
|
47
|
+
to_currency: Target currency code
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Converted amount as string
|
|
51
|
+
"""
|
|
52
|
+
# Mock conversion (in reality, fetch real rates)
|
|
53
|
+
rates = {"USD": 1.0, "EUR": 0.85, "GBP": 0.73, "JPY": 110.0}
|
|
54
|
+
if from_currency not in rates or to_currency not in rates:
|
|
55
|
+
return "Currency not supported"
|
|
56
|
+
|
|
57
|
+
result = amount * (rates[to_currency] / rates[from_currency])
|
|
58
|
+
return f"{amount} {from_currency} = {result:.2f} {to_currency}"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
async def main():
|
|
62
|
+
api_key = os.environ.get("OPENAI_API_KEY")
|
|
63
|
+
if not api_key:
|
|
64
|
+
raise ValueError("Please set OPENAI_API_KEY environment variable")
|
|
65
|
+
|
|
66
|
+
# Create agent with multiple tools
|
|
67
|
+
agent = ReActAgent(
|
|
68
|
+
model="gpt-4o-mini",
|
|
69
|
+
api_key=api_key,
|
|
70
|
+
tools=[
|
|
71
|
+
CalculatorTool(),
|
|
72
|
+
DateTimeTool(),
|
|
73
|
+
get_weather,
|
|
74
|
+
convert_currency,
|
|
75
|
+
],
|
|
76
|
+
verbose=True,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Example queries that require different tools
|
|
80
|
+
queries = [
|
|
81
|
+
"What's the weather in Tokyo and how much is 100 USD in JPY?",
|
|
82
|
+
"Calculate 15% tip on a $45.50 bill and tell me today's date.",
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
for query in queries:
|
|
86
|
+
print(f"\n{'='*60}")
|
|
87
|
+
print(f"Query: {query}")
|
|
88
|
+
print('='*60)
|
|
89
|
+
|
|
90
|
+
result = await agent.run(query)
|
|
91
|
+
print(f"\nFinal Answer: {result}")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLM with Caching and Retry Configuration
|
|
3
|
+
=========================================
|
|
4
|
+
|
|
5
|
+
This example demonstrates how to configure LLM calls with:
|
|
6
|
+
1. Response caching for repeated queries
|
|
7
|
+
2. Automatic retries with exponential backoff
|
|
8
|
+
3. Cost tracking and budget limits
|
|
9
|
+
|
|
10
|
+
Prerequisites:
|
|
11
|
+
pip install synapsekit[openai]
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
export OPENAI_API_KEY=sk-...
|
|
15
|
+
python examples/caching_retries.py
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
19
|
+
import os
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
|
|
22
|
+
from synapsekit import BaseLLM, LLMConfig, CostTracker, BudgetGuard
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Simple in-memory cache implementation
|
|
26
|
+
class SimpleCache:
|
|
27
|
+
"""Simple in-memory cache for demonstration"""
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
self.cache = {}
|
|
31
|
+
|
|
32
|
+
def get(self, key: str):
|
|
33
|
+
"""Get cached value"""
|
|
34
|
+
return self.cache.get(key)
|
|
35
|
+
|
|
36
|
+
def set(self, key: str, value: str):
|
|
37
|
+
"""Set cached value"""
|
|
38
|
+
self.cache[key] = value
|
|
39
|
+
print(f"💾 Cached response for: {key[:50]}...")
|
|
40
|
+
|
|
41
|
+
def clear(self):
|
|
42
|
+
"""Clear cache"""
|
|
43
|
+
self.cache.clear()
|
|
44
|
+
print("🗑️ Cache cleared")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def demo_caching():
|
|
48
|
+
"""Demonstrate response caching"""
|
|
49
|
+
print("\n" + "="*60)
|
|
50
|
+
print("Demo 1: Response Caching")
|
|
51
|
+
print("="*60 + "\n")
|
|
52
|
+
|
|
53
|
+
api_key = os.environ.get("OPENAI_API_KEY")
|
|
54
|
+
if not api_key:
|
|
55
|
+
print("⚠️ OPENAI_API_KEY not set. Skipping demo.")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
from synapsekit.llm.openai import OpenAILLM
|
|
59
|
+
|
|
60
|
+
llm = OpenAILLM(model="gpt-4o-mini", api_key=api_key)
|
|
61
|
+
cache = SimpleCache()
|
|
62
|
+
|
|
63
|
+
prompt = "What is the capital of France?"
|
|
64
|
+
|
|
65
|
+
# First call (no cache)
|
|
66
|
+
print(f"Query: {prompt}")
|
|
67
|
+
start = datetime.now()
|
|
68
|
+
|
|
69
|
+
cached = cache.get(prompt)
|
|
70
|
+
if cached:
|
|
71
|
+
print("✅ Using cached response")
|
|
72
|
+
response = cached
|
|
73
|
+
else:
|
|
74
|
+
print("🔄 Making API call...")
|
|
75
|
+
response = await llm.agenerate(prompt)
|
|
76
|
+
cache.set(prompt, response)
|
|
77
|
+
|
|
78
|
+
elapsed = (datetime.now() - start).total_seconds()
|
|
79
|
+
print(f"Response: {response}")
|
|
80
|
+
print(f"⏱️ Time: {elapsed:.2f}s\n")
|
|
81
|
+
|
|
82
|
+
# Second call (cached)
|
|
83
|
+
print(f"Query (repeated): {prompt}")
|
|
84
|
+
start = datetime.now()
|
|
85
|
+
|
|
86
|
+
cached = cache.get(prompt)
|
|
87
|
+
if cached:
|
|
88
|
+
print("✅ Using cached response")
|
|
89
|
+
response = cached
|
|
90
|
+
else:
|
|
91
|
+
print("🔄 Making API call...")
|
|
92
|
+
response = await llm.agenerate(prompt)
|
|
93
|
+
cache.set(prompt, response)
|
|
94
|
+
|
|
95
|
+
elapsed = (datetime.now() - start).total_seconds()
|
|
96
|
+
print(f"Response: {response}")
|
|
97
|
+
print(f"⏱️ Time: {elapsed:.2f}s (much faster!)\n")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
async def demo_retries():
|
|
101
|
+
"""Demonstrate retry configuration"""
|
|
102
|
+
print("\n" + "="*60)
|
|
103
|
+
print("Demo 2: Retry Configuration")
|
|
104
|
+
print("="*60 + "\n")
|
|
105
|
+
|
|
106
|
+
print("🔧 LLM Config with retries:")
|
|
107
|
+
print(" - Max retries: 3")
|
|
108
|
+
print(" - Timeout: 30s")
|
|
109
|
+
print(" - Exponential backoff\n")
|
|
110
|
+
|
|
111
|
+
# In a real scenario, configure via LLMConfig
|
|
112
|
+
config = LLMConfig(
|
|
113
|
+
max_retries=3,
|
|
114
|
+
timeout=30,
|
|
115
|
+
retry_on_errors=["RateLimitError", "TimeoutError"],
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
print(f"Config: {config}\n")
|
|
119
|
+
print("💡 On API failures, requests will retry automatically with backoff.")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
async def demo_cost_tracking():
|
|
123
|
+
"""Demonstrate cost tracking and budgets"""
|
|
124
|
+
print("\n" + "="*60)
|
|
125
|
+
print("Demo 3: Cost Tracking & Budget Limits")
|
|
126
|
+
print("="*60 + "\n")
|
|
127
|
+
|
|
128
|
+
# Initialize cost tracker
|
|
129
|
+
tracker = CostTracker()
|
|
130
|
+
|
|
131
|
+
# Simulate some API calls
|
|
132
|
+
tracker.add_tokens(model="gpt-4o-mini", prompt_tokens=100, completion_tokens=50)
|
|
133
|
+
tracker.add_tokens(model="gpt-4o-mini", prompt_tokens=200, completion_tokens=75)
|
|
134
|
+
tracker.add_tokens(model="gpt-4o-mini", prompt_tokens=150, completion_tokens=60)
|
|
135
|
+
|
|
136
|
+
print("📊 Cost Summary:")
|
|
137
|
+
print(f" Total tokens: {tracker.total_tokens}")
|
|
138
|
+
print(f" Total cost: ${tracker.total_cost:.4f}\n")
|
|
139
|
+
|
|
140
|
+
# Set up budget guard
|
|
141
|
+
print("🛡️ Setting budget limit: $5.00")
|
|
142
|
+
budget = BudgetGuard(limit=5.0)
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
# Check if under budget
|
|
146
|
+
current_cost = tracker.total_cost
|
|
147
|
+
if budget.check(current_cost):
|
|
148
|
+
print(f"✅ Under budget (${current_cost:.4f} / $5.00)")
|
|
149
|
+
else:
|
|
150
|
+
print(f"❌ Budget exceeded!")
|
|
151
|
+
except Exception as e:
|
|
152
|
+
print(f"⚠️ {e}")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
async def main():
|
|
156
|
+
print("""
|
|
157
|
+
This example demonstrates three key LLM configuration patterns:
|
|
158
|
+
1. Response caching for repeated queries
|
|
159
|
+
2. Automatic retry with exponential backoff
|
|
160
|
+
3. Cost tracking and budget limits
|
|
161
|
+
""")
|
|
162
|
+
|
|
163
|
+
await demo_caching()
|
|
164
|
+
await demo_retries()
|
|
165
|
+
await demo_cost_tracking()
|
|
166
|
+
|
|
167
|
+
print("\n✨ All demos complete!\n")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if __name__ == "__main__":
|
|
171
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Graph Workflow with Conditional Edges
|
|
3
|
+
======================================
|
|
4
|
+
|
|
5
|
+
This example demonstrates SynapseKit's StateGraph for building workflows
|
|
6
|
+
with conditional routing, state management, and visualization.
|
|
7
|
+
|
|
8
|
+
Prerequisites:
|
|
9
|
+
pip install synapsekit[openai]
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
export OPENAI_API_KEY=sk-...
|
|
13
|
+
python examples/graph_workflow.py
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import os
|
|
18
|
+
from typing import Literal
|
|
19
|
+
|
|
20
|
+
from synapsekit import StateGraph, END
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Define workflow state
|
|
24
|
+
class ReviewState:
|
|
25
|
+
"""State for content review workflow"""
|
|
26
|
+
content: str = ""
|
|
27
|
+
word_count: int = 0
|
|
28
|
+
is_approved: bool = False
|
|
29
|
+
feedback: str = ""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Define node functions
|
|
33
|
+
async def count_words(state: ReviewState) -> ReviewState:
|
|
34
|
+
"""Count words in content"""
|
|
35
|
+
words = state.content.split()
|
|
36
|
+
state.word_count = len(words)
|
|
37
|
+
print(f"📊 Word count: {state.word_count}")
|
|
38
|
+
return state
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
async def check_length(state: ReviewState) -> ReviewState:
|
|
42
|
+
"""Check if content meets length requirements"""
|
|
43
|
+
if state.word_count >= 10:
|
|
44
|
+
state.is_approved = True
|
|
45
|
+
state.feedback = "Content length is acceptable."
|
|
46
|
+
else:
|
|
47
|
+
state.is_approved = False
|
|
48
|
+
state.feedback = f"Content too short. Need {10 - state.word_count} more words."
|
|
49
|
+
|
|
50
|
+
print(f"✅ Approved: {state.is_approved}")
|
|
51
|
+
print(f"💬 Feedback: {state.feedback}")
|
|
52
|
+
return state
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
async def approve_content(state: ReviewState) -> ReviewState:
|
|
56
|
+
"""Approve content for publication"""
|
|
57
|
+
print("✨ Content approved for publication!")
|
|
58
|
+
return state
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
async def reject_content(state: ReviewState) -> ReviewState:
|
|
62
|
+
"""Reject content and request revision"""
|
|
63
|
+
print("❌ Content rejected. Revision needed.")
|
|
64
|
+
return state
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# Conditional routing function
|
|
68
|
+
def should_approve(state: ReviewState) -> Literal["approve", "reject"]:
|
|
69
|
+
"""Route based on approval status"""
|
|
70
|
+
return "approve" if state.is_approved else "reject"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
async def main():
|
|
74
|
+
# Build the workflow graph
|
|
75
|
+
graph = StateGraph(ReviewState)
|
|
76
|
+
|
|
77
|
+
# Add nodes
|
|
78
|
+
graph.add_node("count", count_words)
|
|
79
|
+
graph.add_node("check", check_length)
|
|
80
|
+
graph.add_node("approve", approve_content)
|
|
81
|
+
graph.add_node("reject", reject_content)
|
|
82
|
+
|
|
83
|
+
# Add edges
|
|
84
|
+
graph.set_entry_point("count")
|
|
85
|
+
graph.add_edge("count", "check")
|
|
86
|
+
|
|
87
|
+
# Add conditional edge based on approval
|
|
88
|
+
graph.add_conditional_edges(
|
|
89
|
+
"check",
|
|
90
|
+
should_approve,
|
|
91
|
+
{
|
|
92
|
+
"approve": "approve",
|
|
93
|
+
"reject": "reject",
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Both approval and rejection lead to end
|
|
98
|
+
graph.add_edge("approve", END)
|
|
99
|
+
graph.add_edge("reject", END)
|
|
100
|
+
|
|
101
|
+
# Compile the graph
|
|
102
|
+
workflow = graph.compile()
|
|
103
|
+
|
|
104
|
+
# Visualize the graph (optional)
|
|
105
|
+
print("Graph structure:")
|
|
106
|
+
print(workflow.get_mermaid())
|
|
107
|
+
print("\n" + "="*60 + "\n")
|
|
108
|
+
|
|
109
|
+
# Test with different inputs
|
|
110
|
+
test_contents = [
|
|
111
|
+
"Hello world!", # Too short
|
|
112
|
+
"This is a longer piece of content that meets the minimum word count requirement.", # Long enough
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
for i, content in enumerate(test_contents, 1):
|
|
116
|
+
print(f"Test {i}: {content[:50]}...")
|
|
117
|
+
print("-" * 60)
|
|
118
|
+
|
|
119
|
+
result = await workflow.run(ReviewState(content=content))
|
|
120
|
+
print(f"\nFinal state - Approved: {result.is_approved}")
|
|
121
|
+
print("="*60 + "\n")
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
asyncio.run(main())
|