synapsekit 0.6.3__tar.gz → 0.6.4__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-0.6.3 → synapsekit-0.6.4}/PKG-INFO +10 -7
- {synapsekit-0.6.3 → synapsekit-0.6.4}/README.md +7 -6
- {synapsekit-0.6.3 → synapsekit-0.6.4}/pyproject.toml +3 -1
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/__init__.py +15 -1
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/__init__.py +6 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/__init__.py +6 -0
- synapsekit-0.6.4/src/synapsekit/agents/tools/shell.py +70 -0
- synapsekit-0.6.4/src/synapsekit/agents/tools/sql_schema.py +132 -0
- synapsekit-0.6.4/src/synapsekit/agents/tools/web_scraper.py +80 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/__init__.py +7 -1
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/checkpointers/__init__.py +2 -0
- synapsekit-0.6.4/src/synapsekit/graph/checkpointers/json_file.py +40 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/compiled.py +26 -16
- synapsekit-0.6.4/src/synapsekit/llm/_filesystem_cache.py +56 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/base.py +5 -1
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/__init__.py +4 -0
- synapsekit-0.6.4/src/synapsekit/loaders/docx.py +30 -0
- synapsekit-0.6.4/src/synapsekit/loaders/markdown.py +30 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/observability/tracer.py +19 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/__init__.py +2 -0
- synapsekit-0.6.4/src/synapsekit/retrieval/hyde.py +45 -0
- synapsekit-0.6.4/tests/agents/test_shell_tool.py +55 -0
- synapsekit-0.6.4/tests/agents/test_sql_schema.py +64 -0
- synapsekit-0.6.4/tests/agents/test_web_scraper.py +142 -0
- synapsekit-0.6.4/tests/graph/test_json_checkpointer.py +36 -0
- synapsekit-0.6.4/tests/llm/test_filesystem_cache.py +49 -0
- synapsekit-0.6.4/tests/loaders/test_docx_loader.py +47 -0
- synapsekit-0.6.4/tests/loaders/test_markdown_loader.py +52 -0
- synapsekit-0.6.4/tests/retrieval/test_hyde.py +61 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v060_features.py +1 -1
- {synapsekit-0.6.3 → synapsekit-0.6.4}/uv.lock +19 -2
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/profile/README.md +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.github/workflows/ci.yml +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.gitignore +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/.pre-commit-config.yaml +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/CHANGELOG.md +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/CODE_OF_CONDUCT.md +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/CONTRIBUTING.md +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/LICENSE +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/Makefile +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/SECURITY.md +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/assets/banner.svg +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/assets/favicon.svg +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/assets/logo.svg +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/_compat.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/base.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/executor.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/function_calling.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/memory.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/react.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/registry.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tool_decorator.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/calculator.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/datetime_tool.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/file_list.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/file_read.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/file_write.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/http_request.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/human_input.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/json_query.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/python_repl.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/regex_tool.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/sentiment.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/sql_query.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/summarization.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/translation.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/web_search.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/agents/tools/wikipedia.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/embeddings/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/embeddings/backend.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/checkpointers/base.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/checkpointers/memory.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/checkpointers/sqlite.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/edge.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/errors.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/fan_out.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/graph.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/interrupt.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/mermaid.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/node.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/state.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/streaming.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/graph/subgraph.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/_cache.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/_rate_limit.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/_retry.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/_semantic_cache.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/_sqlite_cache.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/anthropic.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/azure_openai.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/bedrock.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/cohere.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/deepseek.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/fireworks.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/gemini.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/groq.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/mistral.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/ollama.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/openai.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/openrouter.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/structured.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/llm/together.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/base.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/csv.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/directory.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/excel.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/html.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/json_loader.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/pdf.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/pptx.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/text.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/loaders/web.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/memory/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/memory/conversation.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/memory/hybrid.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/memory/sqlite.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/memory/summary_buffer.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/observability/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/parsers/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/parsers/json_parser.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/parsers/list_parser.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/parsers/pydantic_parser.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/prompts/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/prompts/template.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/py.typed +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/rag/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/rag/facade.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/rag/pipeline.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/base.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/chroma.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/contextual.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/contextual_compression.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/crag.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/cross_encoder.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/ensemble.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/faiss.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/parent_document.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/pinecone.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/qdrant.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/query_decomposition.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/rag_fusion.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/retriever.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/self_query.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/sentence_window.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/retrieval/vectorstore.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/text_splitters/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/text_splitters/base.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/text_splitters/character.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/text_splitters/recursive.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/text_splitters/semantic.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/src/synapsekit/text_splitters/token.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/test_executor.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/test_function_calling.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/test_memory.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/test_react.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/test_tool_decorator.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/agents/test_tools.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/conftest.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_build.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_checkpointing.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_cycles.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_mermaid.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_run.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_state.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/graph/test_stream.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/llm/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/llm/test_cache_retry.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/llm/test_function_calling_providers.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/llm/test_llm.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/llm/test_providers.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/loaders/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/loaders/test_loaders.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/memory/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/memory/test_memory.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/observability/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/observability/test_tracer.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/parsers/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/parsers/test_parsers.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/prompts/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/prompts/test_prompts.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/rag/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/rag/test_facade.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/rag/test_pipeline.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/retrieval/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/retrieval/test_backends.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/retrieval/test_retriever.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/retrieval/test_vectorstore.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v051_features.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v052_features.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v053_features.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v061_features.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v062_features.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/test_v063_features.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/text_splitters/__init__.py +0 -0
- {synapsekit-0.6.3 → synapsekit-0.6.4}/tests/text_splitters/test_splitters.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synapsekit
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
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
|
|
@@ -43,6 +43,8 @@ Provides-Extra: chroma
|
|
|
43
43
|
Requires-Dist: chromadb>=0.5; extra == 'chroma'
|
|
44
44
|
Provides-Extra: cohere
|
|
45
45
|
Requires-Dist: cohere>=5.0; extra == 'cohere'
|
|
46
|
+
Provides-Extra: docx
|
|
47
|
+
Requires-Dist: python-docx>=1.0; extra == 'docx'
|
|
46
48
|
Provides-Extra: excel
|
|
47
49
|
Requires-Dist: openpyxl>=3.1; extra == 'excel'
|
|
48
50
|
Provides-Extra: faiss
|
|
@@ -88,7 +90,8 @@ Description-Content-Type: text/markdown
|
|
|
88
90
|
[](https://pypi.org/project/synapsekit/)
|
|
89
91
|
[](https://www.python.org/)
|
|
90
92
|
[](LICENSE)
|
|
91
|
-
[]()
|
|
94
|
+
[](https://pypistats.org/packages/synapsekit)
|
|
92
95
|
[](https://synapsekit.github.io/synapsekit-docs/)
|
|
93
96
|
|
|
94
97
|
**[Documentation](https://synapsekit.github.io/synapsekit-docs/) · [Quickstart](https://synapsekit.github.io/synapsekit-docs/docs/getting-started/quickstart) · [API Reference](https://synapsekit.github.io/synapsekit-docs/docs/api/llm) · [Changelog](CHANGELOG.md) · [Report a Bug](https://github.com/SynapseKit/SynapseKit/issues/new?template=bug_report.yml)**
|
|
@@ -121,7 +124,7 @@ Token-level streaming is the default,<br/>not an afterthought.<br/>Works across
|
|
|
121
124
|
<tr>
|
|
122
125
|
<td align="center" width="33%">
|
|
123
126
|
<h3>🔌 One interface</h3>
|
|
124
|
-
|
|
127
|
+
13 LLM providers and 5 vector stores<br/>behind the same API.<br/>Swap without rewriting.
|
|
125
128
|
</td>
|
|
126
129
|
<td align="center" width="33%">
|
|
127
130
|
<h3>🧩 Composable</h3>
|
|
@@ -164,7 +167,7 @@ Retrieval-augmented generation with streaming, BM25 reranking, conversation memo
|
|
|
164
167
|
<td width="50%">
|
|
165
168
|
|
|
166
169
|
**🤖 Agents**<br/>
|
|
167
|
-
ReAct loop (any LLM) and native function calling (OpenAI / Anthropic).
|
|
170
|
+
ReAct loop (any LLM) and native function calling (OpenAI / Anthropic / Gemini / Mistral). 16 built-in tools including calculator, Python REPL, web search, SQL, HTTP, summarization, sentiment analysis, and translation. Fully extensible.
|
|
168
171
|
|
|
169
172
|
</td>
|
|
170
173
|
</tr>
|
|
@@ -172,13 +175,13 @@ ReAct loop (any LLM) and native function calling (OpenAI / Anthropic). Built-in
|
|
|
172
175
|
<td width="50%">
|
|
173
176
|
|
|
174
177
|
**🔀 Graph Workflows**<br/>
|
|
175
|
-
DAG-based async pipelines. Nodes run in waves — parallel nodes execute concurrently. Conditional routing,
|
|
178
|
+
DAG-based async pipelines. Nodes run in waves — parallel nodes execute concurrently. Conditional routing, typed state with reducers, fan-out/fan-in, SSE streaming, event callbacks, human-in-the-loop, checkpointing, and Mermaid export.
|
|
176
179
|
|
|
177
180
|
</td>
|
|
178
181
|
<td width="50%">
|
|
179
182
|
|
|
180
183
|
**🧠 LLM Providers**<br/>
|
|
181
|
-
OpenAI, Anthropic, Ollama, Gemini, Cohere, Mistral, Bedrock — all behind one interface. Auto-detected from the model name. Swap without rewriting.
|
|
184
|
+
OpenAI, Anthropic, Ollama, Gemini, Cohere, Mistral, Bedrock, Azure OpenAI, Groq, DeepSeek, OpenRouter, Together, Fireworks — all behind one interface. Auto-detected from the model name. Swap without rewriting.
|
|
182
185
|
|
|
183
186
|
</td>
|
|
184
187
|
</tr>
|
|
@@ -238,7 +241,7 @@ Everything you need to get started and go deep is in the docs.
|
|
|
238
241
|
| 🗂 [RAG](https://synapsekit.github.io/synapsekit-docs/docs/rag/pipeline) | Pipelines, loaders, retrieval, vector stores |
|
|
239
242
|
| 🤖 [Agents](https://synapsekit.github.io/synapsekit-docs/docs/agents/overview) | ReAct, function calling, tools, executor |
|
|
240
243
|
| 🔀 [Graph Workflows](https://synapsekit.github.io/synapsekit-docs/docs/graph/overview) | DAG pipelines, conditional routing, parallel execution |
|
|
241
|
-
| 🧠 [LLM Providers](https://synapsekit.github.io/synapsekit-docs/docs/llms/overview) | All
|
|
244
|
+
| 🧠 [LLM Providers](https://synapsekit.github.io/synapsekit-docs/docs/llms/overview) | All 13 providers with examples |
|
|
242
245
|
| 📖 [API Reference](https://synapsekit.github.io/synapsekit-docs/docs/api/llm) | Full class and method reference |
|
|
243
246
|
|
|
244
247
|
---
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
[](https://pypi.org/project/synapsekit/)
|
|
8
8
|
[](https://www.python.org/)
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[]()
|
|
11
|
+
[](https://pypistats.org/packages/synapsekit)
|
|
11
12
|
[](https://synapsekit.github.io/synapsekit-docs/)
|
|
12
13
|
|
|
13
14
|
**[Documentation](https://synapsekit.github.io/synapsekit-docs/) · [Quickstart](https://synapsekit.github.io/synapsekit-docs/docs/getting-started/quickstart) · [API Reference](https://synapsekit.github.io/synapsekit-docs/docs/api/llm) · [Changelog](CHANGELOG.md) · [Report a Bug](https://github.com/SynapseKit/SynapseKit/issues/new?template=bug_report.yml)**
|
|
@@ -40,7 +41,7 @@ Token-level streaming is the default,<br/>not an afterthought.<br/>Works across
|
|
|
40
41
|
<tr>
|
|
41
42
|
<td align="center" width="33%">
|
|
42
43
|
<h3>🔌 One interface</h3>
|
|
43
|
-
|
|
44
|
+
13 LLM providers and 5 vector stores<br/>behind the same API.<br/>Swap without rewriting.
|
|
44
45
|
</td>
|
|
45
46
|
<td align="center" width="33%">
|
|
46
47
|
<h3>🧩 Composable</h3>
|
|
@@ -83,7 +84,7 @@ Retrieval-augmented generation with streaming, BM25 reranking, conversation memo
|
|
|
83
84
|
<td width="50%">
|
|
84
85
|
|
|
85
86
|
**🤖 Agents**<br/>
|
|
86
|
-
ReAct loop (any LLM) and native function calling (OpenAI / Anthropic).
|
|
87
|
+
ReAct loop (any LLM) and native function calling (OpenAI / Anthropic / Gemini / Mistral). 16 built-in tools including calculator, Python REPL, web search, SQL, HTTP, summarization, sentiment analysis, and translation. Fully extensible.
|
|
87
88
|
|
|
88
89
|
</td>
|
|
89
90
|
</tr>
|
|
@@ -91,13 +92,13 @@ ReAct loop (any LLM) and native function calling (OpenAI / Anthropic). Built-in
|
|
|
91
92
|
<td width="50%">
|
|
92
93
|
|
|
93
94
|
**🔀 Graph Workflows**<br/>
|
|
94
|
-
DAG-based async pipelines. Nodes run in waves — parallel nodes execute concurrently. Conditional routing,
|
|
95
|
+
DAG-based async pipelines. Nodes run in waves — parallel nodes execute concurrently. Conditional routing, typed state with reducers, fan-out/fan-in, SSE streaming, event callbacks, human-in-the-loop, checkpointing, and Mermaid export.
|
|
95
96
|
|
|
96
97
|
</td>
|
|
97
98
|
<td width="50%">
|
|
98
99
|
|
|
99
100
|
**🧠 LLM Providers**<br/>
|
|
100
|
-
OpenAI, Anthropic, Ollama, Gemini, Cohere, Mistral, Bedrock — all behind one interface. Auto-detected from the model name. Swap without rewriting.
|
|
101
|
+
OpenAI, Anthropic, Ollama, Gemini, Cohere, Mistral, Bedrock, Azure OpenAI, Groq, DeepSeek, OpenRouter, Together, Fireworks — all behind one interface. Auto-detected from the model name. Swap without rewriting.
|
|
101
102
|
|
|
102
103
|
</td>
|
|
103
104
|
</tr>
|
|
@@ -157,7 +158,7 @@ Everything you need to get started and go deep is in the docs.
|
|
|
157
158
|
| 🗂 [RAG](https://synapsekit.github.io/synapsekit-docs/docs/rag/pipeline) | Pipelines, loaders, retrieval, vector stores |
|
|
158
159
|
| 🤖 [Agents](https://synapsekit.github.io/synapsekit-docs/docs/agents/overview) | ReAct, function calling, tools, executor |
|
|
159
160
|
| 🔀 [Graph Workflows](https://synapsekit.github.io/synapsekit-docs/docs/graph/overview) | DAG pipelines, conditional routing, parallel execution |
|
|
160
|
-
| 🧠 [LLM Providers](https://synapsekit.github.io/synapsekit-docs/docs/llms/overview) | All
|
|
161
|
+
| 🧠 [LLM Providers](https://synapsekit.github.io/synapsekit-docs/docs/llms/overview) | All 13 providers with examples |
|
|
161
162
|
| 📖 [API Reference](https://synapsekit.github.io/synapsekit-docs/docs/api/llm) | Full class and method reference |
|
|
162
163
|
|
|
163
164
|
---
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "synapsekit"
|
|
7
|
-
version = "0.6.
|
|
7
|
+
version = "0.6.4"
|
|
8
8
|
description = "Async-native Python framework for building production-grade LLM applications. Streaming-first, 2 dependencies, fully transparent."
|
|
9
9
|
authors = [{ name = "Amit", email = "de.amit.nautiyal@gmail.com" }]
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -48,6 +48,7 @@ bedrock = ["boto3>=1.34"]
|
|
|
48
48
|
groq = ["groq>=0.9"]
|
|
49
49
|
excel = ["openpyxl>=3.1"]
|
|
50
50
|
pptx = ["python-pptx>=0.6"]
|
|
51
|
+
docx = ["python-docx>=1.0"]
|
|
51
52
|
http = ["aiohttp>=3.9"]
|
|
52
53
|
search = ["duckduckgo-search>=6.0"]
|
|
53
54
|
all = [
|
|
@@ -157,6 +158,7 @@ google-generativeai = "google"
|
|
|
157
158
|
beautifulsoup4 = "bs4"
|
|
158
159
|
faiss-cpu = "faiss"
|
|
159
160
|
python-pptx = "pptx"
|
|
161
|
+
python-docx = "docx"
|
|
160
162
|
|
|
161
163
|
[tool.deptry.per_rule_ignores]
|
|
162
164
|
DEP001 = ["sqlalchemy", "pydantic", "aiohttp"]
|
|
@@ -33,11 +33,14 @@ from .agents import (
|
|
|
33
33
|
ReActAgent,
|
|
34
34
|
RegexTool,
|
|
35
35
|
SentimentAnalysisTool,
|
|
36
|
+
ShellTool,
|
|
36
37
|
SQLQueryTool,
|
|
38
|
+
SQLSchemaInspectionTool,
|
|
37
39
|
SummarizationTool,
|
|
38
40
|
ToolRegistry,
|
|
39
41
|
ToolResult,
|
|
40
42
|
TranslationTool,
|
|
43
|
+
WebScraperTool,
|
|
41
44
|
WebSearchTool,
|
|
42
45
|
WikipediaTool,
|
|
43
46
|
tool,
|
|
@@ -58,6 +61,7 @@ from .graph import (
|
|
|
58
61
|
GraphState,
|
|
59
62
|
InMemoryCheckpointer,
|
|
60
63
|
InterruptState,
|
|
64
|
+
JSONFileCheckpointer,
|
|
61
65
|
Node,
|
|
62
66
|
NodeFn,
|
|
63
67
|
SQLiteCheckpointer,
|
|
@@ -78,6 +82,7 @@ from .loaders.csv import CSVLoader
|
|
|
78
82
|
from .loaders.directory import DirectoryLoader
|
|
79
83
|
from .loaders.html import HTMLLoader
|
|
80
84
|
from .loaders.json_loader import JSONLoader
|
|
85
|
+
from .loaders.markdown import MarkdownLoader
|
|
81
86
|
from .loaders.pdf import PDFLoader
|
|
82
87
|
from .loaders.text import StringLoader, TextLoader
|
|
83
88
|
from .loaders.web import WebLoader
|
|
@@ -98,6 +103,7 @@ from .retrieval.contextual_compression import ContextualCompressionRetriever
|
|
|
98
103
|
from .retrieval.crag import CRAGRetriever
|
|
99
104
|
from .retrieval.cross_encoder import CrossEncoderReranker
|
|
100
105
|
from .retrieval.ensemble import EnsembleRetriever
|
|
106
|
+
from .retrieval.hyde import HyDERetriever
|
|
101
107
|
from .retrieval.parent_document import ParentDocumentRetriever
|
|
102
108
|
from .retrieval.query_decomposition import QueryDecompositionRetriever
|
|
103
109
|
from .retrieval.rag_fusion import RAGFusionRetriever
|
|
@@ -113,7 +119,7 @@ from .text_splitters import (
|
|
|
113
119
|
TokenAwareSplitter,
|
|
114
120
|
)
|
|
115
121
|
|
|
116
|
-
__version__ = "0.6.
|
|
122
|
+
__version__ = "0.6.4"
|
|
117
123
|
__all__ = [
|
|
118
124
|
# Facade
|
|
119
125
|
"RAG",
|
|
@@ -146,6 +152,7 @@ __all__ = [
|
|
|
146
152
|
"CRAGRetriever",
|
|
147
153
|
"CrossEncoderReranker",
|
|
148
154
|
"EnsembleRetriever",
|
|
155
|
+
"HyDERetriever",
|
|
149
156
|
"ParentDocumentRetriever",
|
|
150
157
|
"QueryDecompositionRetriever",
|
|
151
158
|
"SelfQueryRetriever",
|
|
@@ -165,6 +172,8 @@ __all__ = [
|
|
|
165
172
|
"CSVLoader",
|
|
166
173
|
"JSONLoader",
|
|
167
174
|
"DirectoryLoader",
|
|
175
|
+
"DocxLoader",
|
|
176
|
+
"MarkdownLoader",
|
|
168
177
|
"WebLoader",
|
|
169
178
|
"ExcelLoader",
|
|
170
179
|
"PowerPointLoader",
|
|
@@ -200,9 +209,12 @@ __all__ = [
|
|
|
200
209
|
"PythonREPLTool",
|
|
201
210
|
"RegexTool",
|
|
202
211
|
"SentimentAnalysisTool",
|
|
212
|
+
"ShellTool",
|
|
203
213
|
"SQLQueryTool",
|
|
214
|
+
"SQLSchemaInspectionTool",
|
|
204
215
|
"SummarizationTool",
|
|
205
216
|
"TranslationTool",
|
|
217
|
+
"WebScraperTool",
|
|
206
218
|
"WebSearchTool",
|
|
207
219
|
"WikipediaTool",
|
|
208
220
|
# Text splitters
|
|
@@ -238,6 +250,7 @@ __all__ = [
|
|
|
238
250
|
# Checkpointers
|
|
239
251
|
"BaseCheckpointer",
|
|
240
252
|
"InMemoryCheckpointer",
|
|
253
|
+
"JSONFileCheckpointer",
|
|
241
254
|
"SQLiteCheckpointer",
|
|
242
255
|
# Structured output
|
|
243
256
|
"generate_structured",
|
|
@@ -258,6 +271,7 @@ _LAZY_IMPORTS = {
|
|
|
258
271
|
"OpenRouterLLM": "llm.openrouter",
|
|
259
272
|
"TogetherLLM": "llm.together",
|
|
260
273
|
# Loaders
|
|
274
|
+
"DocxLoader": "loaders.docx",
|
|
261
275
|
"ExcelLoader": "loaders.excel",
|
|
262
276
|
"PowerPointLoader": "loaders.pptx",
|
|
263
277
|
}
|
|
@@ -17,9 +17,12 @@ from .tools import (
|
|
|
17
17
|
PythonREPLTool,
|
|
18
18
|
RegexTool,
|
|
19
19
|
SentimentAnalysisTool,
|
|
20
|
+
ShellTool,
|
|
20
21
|
SQLQueryTool,
|
|
22
|
+
SQLSchemaInspectionTool,
|
|
21
23
|
SummarizationTool,
|
|
22
24
|
TranslationTool,
|
|
25
|
+
WebScraperTool,
|
|
23
26
|
WebSearchTool,
|
|
24
27
|
WikipediaTool,
|
|
25
28
|
)
|
|
@@ -50,9 +53,12 @@ __all__ = [
|
|
|
50
53
|
"PythonREPLTool",
|
|
51
54
|
"RegexTool",
|
|
52
55
|
"SentimentAnalysisTool",
|
|
56
|
+
"ShellTool",
|
|
53
57
|
"SQLQueryTool",
|
|
58
|
+
"SQLSchemaInspectionTool",
|
|
54
59
|
"SummarizationTool",
|
|
55
60
|
"TranslationTool",
|
|
61
|
+
"WebScraperTool",
|
|
56
62
|
"WebSearchTool",
|
|
57
63
|
"WikipediaTool",
|
|
58
64
|
]
|
|
@@ -9,9 +9,12 @@ from .json_query import JSONQueryTool
|
|
|
9
9
|
from .python_repl import PythonREPLTool
|
|
10
10
|
from .regex_tool import RegexTool
|
|
11
11
|
from .sentiment import SentimentAnalysisTool
|
|
12
|
+
from .shell import ShellTool
|
|
12
13
|
from .sql_query import SQLQueryTool
|
|
14
|
+
from .sql_schema import SQLSchemaInspectionTool
|
|
13
15
|
from .summarization import SummarizationTool
|
|
14
16
|
from .translation import TranslationTool
|
|
17
|
+
from .web_scraper import WebScraperTool
|
|
15
18
|
from .web_search import WebSearchTool
|
|
16
19
|
from .wikipedia import WikipediaTool
|
|
17
20
|
|
|
@@ -27,9 +30,12 @@ __all__ = [
|
|
|
27
30
|
"PythonREPLTool",
|
|
28
31
|
"RegexTool",
|
|
29
32
|
"SentimentAnalysisTool",
|
|
33
|
+
"ShellTool",
|
|
30
34
|
"SQLQueryTool",
|
|
35
|
+
"SQLSchemaInspectionTool",
|
|
31
36
|
"SummarizationTool",
|
|
32
37
|
"TranslationTool",
|
|
38
|
+
"WebScraperTool",
|
|
33
39
|
"WebSearchTool",
|
|
34
40
|
"WikipediaTool",
|
|
35
41
|
]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from ..base import BaseTool, ToolResult
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ShellTool(BaseTool):
|
|
10
|
+
"""Execute shell commands and return their output."""
|
|
11
|
+
|
|
12
|
+
name = "shell"
|
|
13
|
+
description = (
|
|
14
|
+
"Execute a shell command and return stdout/stderr. "
|
|
15
|
+
"Input: a command string. "
|
|
16
|
+
"Optional: allowed_commands to restrict which commands can be run."
|
|
17
|
+
)
|
|
18
|
+
parameters = {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"command": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "The shell command to execute",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
"required": ["command"],
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
timeout: int = 30,
|
|
32
|
+
allowed_commands: list[str] | None = None,
|
|
33
|
+
) -> None:
|
|
34
|
+
self.timeout = timeout
|
|
35
|
+
self.allowed_commands = allowed_commands
|
|
36
|
+
|
|
37
|
+
async def run(self, command: str = "", **kwargs: Any) -> ToolResult:
|
|
38
|
+
"""Execute the shell command."""
|
|
39
|
+
target = command or kwargs.get("input", "")
|
|
40
|
+
if not target:
|
|
41
|
+
return ToolResult(output="", error="No command provided.")
|
|
42
|
+
|
|
43
|
+
if self.allowed_commands is not None:
|
|
44
|
+
base_cmd = target.split()[0]
|
|
45
|
+
if base_cmd not in self.allowed_commands:
|
|
46
|
+
return ToolResult(
|
|
47
|
+
output="",
|
|
48
|
+
error=f"Command {base_cmd!r} is not in the allowed list.",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
proc = await asyncio.create_subprocess_shell(
|
|
53
|
+
target,
|
|
54
|
+
stdout=asyncio.subprocess.PIPE,
|
|
55
|
+
stderr=asyncio.subprocess.PIPE,
|
|
56
|
+
)
|
|
57
|
+
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=self.timeout)
|
|
58
|
+
output = stdout.decode() if stdout else ""
|
|
59
|
+
err = stderr.decode() if stderr else ""
|
|
60
|
+
|
|
61
|
+
if proc.returncode != 0:
|
|
62
|
+
return ToolResult(
|
|
63
|
+
output=output,
|
|
64
|
+
error=f"Exit code {proc.returncode}: {err}".strip(),
|
|
65
|
+
)
|
|
66
|
+
return ToolResult(output=output + err)
|
|
67
|
+
except TimeoutError:
|
|
68
|
+
return ToolResult(output="", error=f"Command timed out after {self.timeout}s.")
|
|
69
|
+
except Exception as e:
|
|
70
|
+
return ToolResult(output="", error=f"Shell error: {e}")
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sqlite3
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from ..base import BaseTool, ToolResult
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SQLSchemaInspectionTool(BaseTool):
|
|
10
|
+
"""Inspect database schema: list tables and describe columns."""
|
|
11
|
+
|
|
12
|
+
name = "sql_schema"
|
|
13
|
+
description = (
|
|
14
|
+
"Inspect the schema of a SQL database. "
|
|
15
|
+
"Actions: 'list_tables' returns all table names, "
|
|
16
|
+
"'describe_table' returns column details for a given table. "
|
|
17
|
+
"Input: action (required), table_name (optional, for describe_table)."
|
|
18
|
+
)
|
|
19
|
+
parameters = {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"properties": {
|
|
22
|
+
"action": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "The action to perform: 'list_tables' or 'describe_table'",
|
|
25
|
+
"enum": ["list_tables", "describe_table"],
|
|
26
|
+
},
|
|
27
|
+
"table_name": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Table name (required for describe_table)",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
"required": ["action"],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
def __init__(self, connection_string: str) -> None:
|
|
36
|
+
self._connection_string = connection_string
|
|
37
|
+
|
|
38
|
+
def _is_sqlite(self) -> bool:
|
|
39
|
+
return self._connection_string.endswith(".db") or self._connection_string == ":memory:"
|
|
40
|
+
|
|
41
|
+
def _list_tables_sqlite(self) -> list[str]:
|
|
42
|
+
conn = sqlite3.connect(self._connection_string)
|
|
43
|
+
try:
|
|
44
|
+
rows = conn.execute(
|
|
45
|
+
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
|
46
|
+
).fetchall()
|
|
47
|
+
return [r[0] for r in rows]
|
|
48
|
+
finally:
|
|
49
|
+
conn.close()
|
|
50
|
+
|
|
51
|
+
def _describe_table_sqlite(self, table_name: str) -> list[dict[str, Any]]:
|
|
52
|
+
conn = sqlite3.connect(self._connection_string)
|
|
53
|
+
try:
|
|
54
|
+
rows = conn.execute(f"PRAGMA table_info({table_name})").fetchall()
|
|
55
|
+
return [
|
|
56
|
+
{
|
|
57
|
+
"name": r[1],
|
|
58
|
+
"type": r[2],
|
|
59
|
+
"nullable": not r[3],
|
|
60
|
+
"pk": bool(r[5]),
|
|
61
|
+
}
|
|
62
|
+
for r in rows
|
|
63
|
+
]
|
|
64
|
+
finally:
|
|
65
|
+
conn.close()
|
|
66
|
+
|
|
67
|
+
def _list_tables_sqlalchemy(self) -> list[str]:
|
|
68
|
+
try:
|
|
69
|
+
from sqlalchemy import create_engine, inspect
|
|
70
|
+
except ImportError:
|
|
71
|
+
raise ImportError(
|
|
72
|
+
"sqlalchemy required for non-SQLite databases: pip install sqlalchemy"
|
|
73
|
+
) from None
|
|
74
|
+
engine = create_engine(self._connection_string)
|
|
75
|
+
inspector = inspect(engine)
|
|
76
|
+
return sorted(inspector.get_table_names())
|
|
77
|
+
|
|
78
|
+
def _describe_table_sqlalchemy(self, table_name: str) -> list[dict[str, Any]]:
|
|
79
|
+
try:
|
|
80
|
+
from sqlalchemy import create_engine, inspect
|
|
81
|
+
except ImportError:
|
|
82
|
+
raise ImportError(
|
|
83
|
+
"sqlalchemy required for non-SQLite databases: pip install sqlalchemy"
|
|
84
|
+
) from None
|
|
85
|
+
engine = create_engine(self._connection_string)
|
|
86
|
+
inspector = inspect(engine)
|
|
87
|
+
columns = inspector.get_columns(table_name)
|
|
88
|
+
pk_cols = {
|
|
89
|
+
c for c in (inspector.get_pk_constraint(table_name).get("constrained_columns") or [])
|
|
90
|
+
}
|
|
91
|
+
return [
|
|
92
|
+
{
|
|
93
|
+
"name": col["name"],
|
|
94
|
+
"type": str(col["type"]),
|
|
95
|
+
"nullable": col.get("nullable", True),
|
|
96
|
+
"pk": col["name"] in pk_cols,
|
|
97
|
+
}
|
|
98
|
+
for col in columns
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
async def run(self, action: str = "", table_name: str = "", **kwargs: Any) -> ToolResult:
|
|
102
|
+
if not action:
|
|
103
|
+
return ToolResult(output="", error="action is required.")
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
if action == "list_tables":
|
|
107
|
+
if self._is_sqlite():
|
|
108
|
+
tables = self._list_tables_sqlite()
|
|
109
|
+
else:
|
|
110
|
+
tables = self._list_tables_sqlalchemy()
|
|
111
|
+
return ToolResult(output=", ".join(tables) if tables else "(no tables)")
|
|
112
|
+
|
|
113
|
+
if action == "describe_table":
|
|
114
|
+
if not table_name:
|
|
115
|
+
return ToolResult(output="", error="table_name is required for describe_table.")
|
|
116
|
+
if self._is_sqlite():
|
|
117
|
+
cols = self._describe_table_sqlite(table_name)
|
|
118
|
+
else:
|
|
119
|
+
cols = self._describe_table_sqlalchemy(table_name)
|
|
120
|
+
if not cols:
|
|
121
|
+
return ToolResult(
|
|
122
|
+
output="", error=f"Table {table_name!r} not found or has no columns."
|
|
123
|
+
)
|
|
124
|
+
lines = [
|
|
125
|
+
f"{c['name']} ({c['type']}, nullable={c['nullable']}, pk={c['pk']})"
|
|
126
|
+
for c in cols
|
|
127
|
+
]
|
|
128
|
+
return ToolResult(output="\n".join(lines))
|
|
129
|
+
|
|
130
|
+
return ToolResult(output="", error=f"Unknown action: {action!r}")
|
|
131
|
+
except Exception as e:
|
|
132
|
+
return ToolResult(output="", error=f"SQL schema error: {e}")
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from ..base import BaseTool, ToolResult
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WebScraperTool(BaseTool):
|
|
9
|
+
"""Fetch a URL and extract clean text content from the webpage."""
|
|
10
|
+
|
|
11
|
+
name = "web_scraper"
|
|
12
|
+
description = (
|
|
13
|
+
"Fetch a webpage URL and return clean text content. "
|
|
14
|
+
"Input: a URL string, e.g. 'https://example.com/article'. "
|
|
15
|
+
"Optional: css_selector to extract specific content. "
|
|
16
|
+
"Removes scripts, styles, nav, header, footer elements."
|
|
17
|
+
)
|
|
18
|
+
parameters = {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"url": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "The URL of the webpage to scrape",
|
|
24
|
+
},
|
|
25
|
+
"css_selector": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Optional CSS selector to extract specific content (e.g. 'article', '.content')",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
"required": ["url"],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
def __init__(self, timeout: int = 30):
|
|
34
|
+
self.timeout = timeout
|
|
35
|
+
|
|
36
|
+
def _clean_html(self, html: str, css_selector: str | None = None) -> str:
|
|
37
|
+
"""Parse HTML and extract clean text."""
|
|
38
|
+
try:
|
|
39
|
+
from bs4 import BeautifulSoup
|
|
40
|
+
except ImportError:
|
|
41
|
+
raise ImportError("beautifulsoup4 required: pip install synapsekit[web]") from None
|
|
42
|
+
|
|
43
|
+
soup = BeautifulSoup(html, "html.parser")
|
|
44
|
+
|
|
45
|
+
for element in soup(["script", "style", "nav", "header", "footer", "aside"]):
|
|
46
|
+
element.decompose()
|
|
47
|
+
|
|
48
|
+
if css_selector:
|
|
49
|
+
elements = soup.select(css_selector)
|
|
50
|
+
if not elements:
|
|
51
|
+
return ""
|
|
52
|
+
content = "\n\n".join(elem.get_text(separator="\n", strip=True) for elem in elements)
|
|
53
|
+
else:
|
|
54
|
+
content = soup.get_text(separator="\n", strip=True)
|
|
55
|
+
|
|
56
|
+
return content
|
|
57
|
+
|
|
58
|
+
async def run(
|
|
59
|
+
self, url: str = "", css_selector: str | None = None, **kwargs: Any
|
|
60
|
+
) -> ToolResult:
|
|
61
|
+
"""Fetch URL and return clean text."""
|
|
62
|
+
try:
|
|
63
|
+
import httpx
|
|
64
|
+
except ImportError:
|
|
65
|
+
raise ImportError("httpx required: pip install synapsekit[web]") from None
|
|
66
|
+
|
|
67
|
+
target_url = url or kwargs.get("input", "")
|
|
68
|
+
if not target_url:
|
|
69
|
+
return ToolResult(output="", error="No URL provided.")
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
async with httpx.AsyncClient() as client:
|
|
73
|
+
response = await client.get(target_url, timeout=self.timeout)
|
|
74
|
+
response.raise_for_status()
|
|
75
|
+
text = self._clean_html(response.text, css_selector)
|
|
76
|
+
return ToolResult(output=text)
|
|
77
|
+
except httpx.HTTPError as e:
|
|
78
|
+
return ToolResult(output="", error=f"HTTP error: {e}")
|
|
79
|
+
except Exception as e:
|
|
80
|
+
return ToolResult(output="", error=f"Scraping failed: {e}")
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
from .checkpointers import
|
|
1
|
+
from .checkpointers import (
|
|
2
|
+
BaseCheckpointer,
|
|
3
|
+
InMemoryCheckpointer,
|
|
4
|
+
JSONFileCheckpointer,
|
|
5
|
+
SQLiteCheckpointer,
|
|
6
|
+
)
|
|
2
7
|
from .compiled import CompiledGraph
|
|
3
8
|
from .edge import ConditionalEdge, ConditionFn, Edge
|
|
4
9
|
from .errors import GraphConfigError, GraphRuntimeError
|
|
@@ -25,6 +30,7 @@ __all__ = [
|
|
|
25
30
|
"GraphState",
|
|
26
31
|
"InMemoryCheckpointer",
|
|
27
32
|
"InterruptState",
|
|
33
|
+
"JSONFileCheckpointer",
|
|
28
34
|
"Node",
|
|
29
35
|
"NodeFn",
|
|
30
36
|
"SQLiteCheckpointer",
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from .base import BaseCheckpointer
|
|
2
|
+
from .json_file import JSONFileCheckpointer
|
|
2
3
|
from .memory import InMemoryCheckpointer
|
|
3
4
|
from .sqlite import SQLiteCheckpointer
|
|
4
5
|
|
|
5
6
|
__all__ = [
|
|
6
7
|
"BaseCheckpointer",
|
|
7
8
|
"InMemoryCheckpointer",
|
|
9
|
+
"JSONFileCheckpointer",
|
|
8
10
|
"SQLiteCheckpointer",
|
|
9
11
|
]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from .base import BaseCheckpointer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class JSONFileCheckpointer(BaseCheckpointer):
|
|
11
|
+
"""File-based checkpointer using JSON files.
|
|
12
|
+
|
|
13
|
+
Each graph checkpoint is stored as a separate JSON file named
|
|
14
|
+
``{graph_id}.json`` in the given directory.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, directory: str = ".") -> None:
|
|
18
|
+
self._directory = directory
|
|
19
|
+
os.makedirs(directory, exist_ok=True)
|
|
20
|
+
|
|
21
|
+
def _path_for(self, graph_id: str) -> str:
|
|
22
|
+
return os.path.join(self._directory, f"{graph_id}.json")
|
|
23
|
+
|
|
24
|
+
def save(self, graph_id: str, step: int, state: dict[str, Any]) -> None:
|
|
25
|
+
path = self._path_for(graph_id)
|
|
26
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
27
|
+
json.dump({"step": step, "state": state}, f)
|
|
28
|
+
|
|
29
|
+
def load(self, graph_id: str) -> tuple[int, dict[str, Any]] | None:
|
|
30
|
+
path = self._path_for(graph_id)
|
|
31
|
+
if not os.path.exists(path):
|
|
32
|
+
return None
|
|
33
|
+
with open(path, encoding="utf-8") as f:
|
|
34
|
+
data = json.load(f)
|
|
35
|
+
return data["step"], data["state"]
|
|
36
|
+
|
|
37
|
+
def delete(self, graph_id: str) -> None:
|
|
38
|
+
path = self._path_for(graph_id)
|
|
39
|
+
if os.path.exists(path):
|
|
40
|
+
os.remove(path)
|