synapse-framework 0.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. synapse/__init__.py +207 -0
  2. synapse/app.py +942 -0
  3. synapse/cli.py +88 -0
  4. synapse/config.py +103 -0
  5. synapse/connectors/__init__.py +29 -0
  6. synapse/connectors/base.py +222 -0
  7. synapse/connectors/factory.py +202 -0
  8. synapse/connectors/gmail.py +292 -0
  9. synapse/connectors/mcp_wrapper.py +153 -0
  10. synapse/connectors/notion.py +161 -0
  11. synapse/connectors/photos.py +141 -0
  12. synapse/database/__init__.py +19 -0
  13. synapse/database/base.py +63 -0
  14. synapse/database/chroma.py +175 -0
  15. synapse/database/memory.py +132 -0
  16. synapse/database/pgvector.py +99 -0
  17. synapse/database/qdrant.py +138 -0
  18. synapse/embeddings/__init__.py +21 -0
  19. synapse/embeddings/base.py +262 -0
  20. synapse/export/__init__.py +14 -0
  21. synapse/export/mcp_exporter.py +202 -0
  22. synapse/graph/__init__.py +21 -0
  23. synapse/graph/base.py +130 -0
  24. synapse/graph/memory.py +20 -0
  25. synapse/graph/neo4j_store.py +176 -0
  26. synapse/graph/networkx_store.py +221 -0
  27. synapse/inspector/__init__.py +5 -0
  28. synapse/inspector/template.py +530 -0
  29. synapse/models/__init__.py +73 -0
  30. synapse/models/base.py +95 -0
  31. synapse/models/gemini.py +328 -0
  32. synapse/models/ollama.py +322 -0
  33. synapse/models/openai.py +289 -0
  34. synapse/oauth/__init__.py +7 -0
  35. synapse/oauth/google.py +194 -0
  36. synapse/oauth/notion.py +35 -0
  37. synapse/rag/__init__.py +8 -0
  38. synapse/rag/chunker.py +219 -0
  39. synapse/rag/hybrid_rag.py +122 -0
  40. synapse/resource/__init__.py +5 -0
  41. synapse/resource/resource.py +304 -0
  42. synapse/resources/__init__.py +5 -0
  43. synapse/skills/__init__.py +5 -0
  44. synapse/skills/skill.py +321 -0
  45. synapse/storage/__init__.py +24 -0
  46. synapse/storage/graph_exporter.py +624 -0
  47. synapse/storage/graph_store.py +162 -0
  48. synapse/storage/vector_store.py +103 -0
  49. synapse_framework-0.2.4.dist-info/METADATA +415 -0
  50. synapse_framework-0.2.4.dist-info/RECORD +54 -0
  51. synapse_framework-0.2.4.dist-info/WHEEL +5 -0
  52. synapse_framework-0.2.4.dist-info/entry_points.txt +2 -0
  53. synapse_framework-0.2.4.dist-info/licenses/LICENSE +21 -0
  54. synapse_framework-0.2.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,162 @@
1
+ """Persistent directed knowledge graph storage backed by NetworkX and JSON."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ import networkx as nx
11
+
12
+ from synapse.config import DEFAULT_GRAPH_FILE, DESIGN_TOKENS
13
+ from synapse.graph.networkx_store import NetworkXGraph
14
+
15
+ PALETTE: dict[str, str] = DESIGN_TOKENS["palettes"]["zinc"]
16
+
17
+
18
+ class PersistentGraphStore(NetworkXGraph):
19
+ """Manages a persistent directed graph of entities and relations."""
20
+
21
+ def __init__(self, filepath: str | Path | None = None) -> None:
22
+ """Initializes the graph store from a persistent JSON file."""
23
+ super().__init__(filepath=filepath or DEFAULT_GRAPH_FILE)
24
+
25
+ def add_node_entity(
26
+ self,
27
+ name: str,
28
+ entity_type: str = "Default",
29
+ color: str | None = None,
30
+ attributes: dict[str, Any] | None = None,
31
+ ) -> None:
32
+ """Adds or updates an entity node in the graph."""
33
+ clean_name = name.strip()
34
+ if not clean_name:
35
+ return
36
+
37
+ assigned_color = color or self.palette.get(
38
+ entity_type, self.palette["Default"]
39
+ )
40
+ node_data: dict[str, Any] = {
41
+ "name": clean_name,
42
+ "type": entity_type,
43
+ "color": assigned_color,
44
+ }
45
+ if attributes:
46
+ node_data.update(attributes)
47
+
48
+ if self.graph.has_node(clean_name):
49
+ self.graph.nodes[clean_name].update(node_data)
50
+ else:
51
+ self.graph.add_node(clean_name, **node_data)
52
+
53
+ self.save()
54
+
55
+ def add_relation(
56
+ self,
57
+ source: str,
58
+ relation: str,
59
+ target: str,
60
+ source_type: str = "Default",
61
+ target_type: str = "Default",
62
+ metadata: dict[str, Any] | None = None,
63
+ ) -> None:
64
+ """Creates a directed relation edge between source and target entities."""
65
+ clean_source = source.strip()
66
+ clean_target = target.strip()
67
+ clean_rel = relation.strip().upper()
68
+
69
+ if not clean_source or not clean_target:
70
+ return
71
+
72
+ if not self.graph.has_node(clean_source):
73
+ self.add_node_entity(clean_source, entity_type=source_type)
74
+ if not self.graph.has_node(clean_target):
75
+ self.add_node_entity(clean_target, entity_type=target_type)
76
+
77
+ edge_data: dict[str, Any] = {"relation": clean_rel}
78
+ if metadata:
79
+ edge_data.update(metadata)
80
+
81
+ self.graph.add_edge(clean_source, clean_target, **edge_data)
82
+ self.save()
83
+
84
+ def find_relation_for(self, entity_name: str) -> list[str]:
85
+ """Retrieves incoming and outgoing relational facts for an entity."""
86
+ clean_entity = entity_name.strip()
87
+ facts: list[str] = []
88
+
89
+ if not self.graph.has_node(clean_entity):
90
+ return facts
91
+
92
+ for neighbor in self.graph.successors(clean_entity):
93
+ edge_data = self.graph.get_edge_data(clean_entity, neighbor) or {}
94
+ rel = edge_data.get("relation", "CONNECTED_TO")
95
+ facts.append(f"{clean_entity} -> {rel} -> {neighbor}")
96
+
97
+ for neighbor in self.graph.predecessors(clean_entity):
98
+ edge_data = self.graph.get_edge_data(neighbor, clean_entity) or {}
99
+ rel = edge_data.get("relation", "CONNECTED_TO")
100
+ facts.append(f"{neighbor} -> {rel} -> {clean_entity}")
101
+
102
+ return facts
103
+
104
+ def get_3d_payload(self) -> dict[str, Any]:
105
+ """Serializes the graph into 3D Force-Graph nodes and links."""
106
+ nodes: list[dict[str, Any]] = []
107
+ for node_id, data in self.graph.nodes(data=True):
108
+ node_type = data.get("type", "Default")
109
+ color = data.get(
110
+ "color", self.palette.get(node_type, self.palette["Default"])
111
+ )
112
+ degree = self.graph.degree(node_id)
113
+ node_size = max(3, min(14, degree * 2))
114
+
115
+ nodes.append({
116
+ "id": str(node_id),
117
+ "name": str(node_id),
118
+ "type": node_type,
119
+ "color": color,
120
+ "val": node_size,
121
+ "attributes": {
122
+ k: v
123
+ for k, v in data.items()
124
+ if k not in ["type", "color", "name"]
125
+ },
126
+ })
127
+
128
+ links: list[dict[str, Any]] = []
129
+ for u, v, data in self.graph.edges(data=True):
130
+ links.append({
131
+ "source": str(u),
132
+ "target": str(v),
133
+ "relation": data.get("relation", "CONNECTED_TO"),
134
+ })
135
+
136
+ return {"nodes": nodes, "links": links}
137
+
138
+ def load(self) -> None:
139
+ """Loads graph data from JSON file on disk."""
140
+ if os.path.exists(self.filepath):
141
+ try:
142
+ with open(self.filepath, "r", encoding="utf-8") as f:
143
+ data = json.load(f)
144
+ if "edges" in data and "links" not in data:
145
+ data["links"] = data.pop("edges")
146
+ self.graph = nx.node_link_graph(data, directed=True)
147
+ except Exception:
148
+ self.graph = nx.DiGraph()
149
+
150
+ def save(self) -> None:
151
+ """Saves current graph to disk."""
152
+ self.filepath.parent.mkdir(parents=True, exist_ok=True)
153
+ data = nx.node_link_data(self.graph)
154
+ with open(self.filepath, "w", encoding="utf-8") as f:
155
+ json.dump(data, f, indent=2)
156
+
157
+ def get_stats(self) -> dict[str, int]:
158
+ """Returns node and edge counts."""
159
+ return {
160
+ "total_nodes": self.graph.number_of_nodes(),
161
+ "total_edges": self.graph.number_of_edges(),
162
+ }
@@ -0,0 +1,103 @@
1
+ """Pluggable persistent and in-memory vector storage for Synapse."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ from langchain_core.documents import Document
9
+
10
+ from synapse.config import (
11
+ DEFAULT_CHROMA_COLLECTION,
12
+ DEFAULT_CHROMA_DIR,
13
+ )
14
+ from synapse.database.base import BaseVectorDB
15
+ from synapse.database.chroma import ChromaDB
16
+
17
+
18
+ class VectorStorage:
19
+ """Universal vector storage container wrapping pluggable database backends.
20
+
21
+ Example:
22
+ ```python
23
+ from synapse.database import chromadb, in_memory
24
+ from synapse.storage import vectorStorage
25
+
26
+ # With persistent ChromaDB:
27
+ storage = vectorStorage(database=chromadb("data/chroma_db"))
28
+
29
+ # With pure in-memory database:
30
+ storage = vectorStorage(database=in_memory())
31
+
32
+ # With remote online ChromaDB:
33
+ storage = vectorStorage(database=chromadb(host="localhost", port=8000))
34
+ ```
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ database: BaseVectorDB | None = None,
40
+ persist_dir: str | Path | None = None,
41
+ collection_name: str = DEFAULT_CHROMA_COLLECTION,
42
+ embedding: str | Any | None = None,
43
+ embedding_model: str | None = None,
44
+ **kwargs: Any,
45
+ ) -> None:
46
+ """Initializes the VectorStorage container.
47
+
48
+ Args:
49
+ database: Optional BaseVectorDB instance (e.g. chromadb(), in_memory(), qdrant()).
50
+ persist_dir: Optional filesystem path for local ChromaDB if database not provided.
51
+ collection_name: Collection name. Defaults to 'synapse_memory'.
52
+ embedding: Embedding model name ('fastembed', 'minilm', 'openai', etc.) or Embeddings object.
53
+ embedding_model: Backward-compatible alias for embedding model name.
54
+ **kwargs: Extra database parameters.
55
+ """
56
+ if database is not None:
57
+ self.database = database
58
+ else:
59
+ # Default to ChromaDB backend
60
+ target_path = persist_dir or DEFAULT_CHROMA_DIR
61
+ self.database = ChromaDB(
62
+ path=target_path,
63
+ collection_name=collection_name,
64
+ embedding=embedding,
65
+ embedding_model=embedding_model,
66
+ **kwargs,
67
+ )
68
+
69
+ def add_documents(self, documents: list[Document]) -> list[str]:
70
+ """Upserts documents into the underlying database."""
71
+ return self.database.add_documents(documents)
72
+
73
+ def similarity_search(
74
+ self,
75
+ query: str,
76
+ k: int = 4,
77
+ filter_dict: dict[str, Any] | None = None,
78
+ ) -> list[Document]:
79
+ """Performs nearest-neighbor semantic search."""
80
+ return self.database.similarity_search(query=query, k=k, filter_dict=filter_dict)
81
+
82
+ def count(self) -> int:
83
+ """Returns the total number of document chunks currently indexed."""
84
+ return self.database.count()
85
+
86
+ def clear(self) -> None:
87
+ """Clears all indexed records."""
88
+ self.database.clear()
89
+
90
+
91
+ # Developer-friendly alias matching user specification
92
+ vectorStorage = VectorStorage
93
+
94
+ # Backwards-compatible aliases
95
+ LocalVectorStore = VectorStorage
96
+ LocalVectorStorage = VectorStorage
97
+
98
+ __all__ = [
99
+ "LocalVectorStorage",
100
+ "LocalVectorStore",
101
+ "VectorStorage",
102
+ "vectorStorage",
103
+ ]
@@ -0,0 +1,415 @@
1
+ Metadata-Version: 2.4
2
+ Name: synapse-framework
3
+ Version: 0.2.4
4
+ Summary: Modular Multi-MCP & Hybrid RAG AI Application Framework
5
+ Author: Synapse Contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/AKASH-KUMAR-BARPANDA/synapse-framework
8
+ Project-URL: Repository, https://github.com/AKASH-KUMAR-BARPANDA/synapse-framework
9
+ Project-URL: Issues, https://github.com/AKASH-KUMAR-BARPANDA/synapse-framework/issues
10
+ Keywords: mcp,rag,agents,knowledge-graph,fastapi,claude,cursor,ollama,chromadb,qdrant,networkx,ai
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: chromadb>=1.5.9
24
+ Requires-Dist: fastapi[standard]>=0.142.2
25
+ Requires-Dist: fastembed>=0.8.1
26
+ Requires-Dist: google-api-python-client>=2.201.0
27
+ Requires-Dist: google-auth-httplib2>=0.4.4
28
+ Requires-Dist: google-auth-oauthlib>=1.5.0
29
+ Requires-Dist: httpx>=0.28.1
30
+ Requires-Dist: langchain>=1.4.3
31
+ Requires-Dist: langchain-chroma>=1.1.0
32
+ Requires-Dist: langchain-community>=0.4.2
33
+ Requires-Dist: langchain-core>=1.6.7
34
+ Requires-Dist: langchain-ollama>=1.1.0
35
+ Requires-Dist: matplotlib>=3.11.2
36
+ Requires-Dist: mcp>=2.3.0
37
+ Requires-Dist: networkx>=3.7
38
+ Requires-Dist: pydantic>=2.13.5
39
+ Requires-Dist: uvicorn>=0.30.0
40
+ Provides-Extra: qdrant
41
+ Requires-Dist: qdrant-client>=1.12.0; extra == "qdrant"
42
+ Provides-Extra: all
43
+ Requires-Dist: qdrant-client>=1.12.0; extra == "all"
44
+ Provides-Extra: dev
45
+ Requires-Dist: bandit>=1.9.0; extra == "dev"
46
+ Requires-Dist: build>=1.2.0; extra == "dev"
47
+ Requires-Dist: pip-audit>=2.8.0; extra == "dev"
48
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
49
+ Requires-Dist: twine>=6.0.0; extra == "dev"
50
+ Dynamic: license-file
51
+
52
+ <p align="center">
53
+ <img src="assets/logo.png" width="160" height="160" alt="Synapse Logo" style="border-radius: 36px; box-shadow: 0 12px 36px rgba(0,0,0,0.4);"/>
54
+ </p>
55
+
56
+ <h1 align="center">Synapse</h1>
57
+
58
+ <p align="center">
59
+ <b>Modular Multi-MCP & Hybrid RAG AI Application Framework</b>
60
+ </p>
61
+
62
+ <p align="center">
63
+ <a href="https://pypi.org/project/synapse-framework/"><img src="https://img.shields.io/pypi/v/synapse-framework.svg?color=6366F1&label=PyPI" alt="PyPI version"/></a>
64
+ <a href="https://pypi.org/project/synapse-framework/"><img src="https://img.shields.io/pypi/pyversions/synapse-framework.svg?color=06B6D4" alt="Python Versions"/></a>
65
+ <a href="https://github.com/AKASH-KUMAR-BARPANDA/synapse-framework/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"/></a>
66
+ <a href="https://github.com/AKASH-KUMAR-BARPANDA/synapse-framework/actions"><img src="https://img.shields.io/badge/tests-23%20passing-success.svg?color=10B981" alt="Tests"/></a>
67
+ <a href="https://github.com/PyCQA/bandit"><img src="https://img.shields.io/badge/security-bandit%20passed-success.svg?color=10B981" alt="Bandit Security"/></a>
68
+ </p>
69
+
70
+ <p align="center">
71
+ <a href="#-quickstart">Quickstart</a> β€’
72
+ <a href="#-key-features">Features</a> β€’
73
+ <a href="#-interactive-inspector--3d-graph">Inspector & Graph</a> β€’
74
+ <a href="#-core-architecture">Architecture</a> β€’
75
+ <a href="#-api-endpoint-reference">API Endpoints</a> β€’
76
+ <a href="#-claude-desktop--cursor-export">MCP Export</a> β€’
77
+ <a href="#-license">License</a>
78
+ </p>
79
+
80
+ ---
81
+
82
+ **Synapse** is an open-source, local-first Python framework for developing autonomous AI assistants, multi-tool agents, and intelligent backend services. It unifies **Model Context Protocol (MCP)** tool execution, **Hybrid RAG** (vector embeddings combined with directed knowledge graphs), pluggable inference providers (**Ollama**, **Google Gemini**, **OpenAI**), and a real-time developer inspector with an interactive 3D WebGL knowledge visualizer.
83
+
84
+ ---
85
+
86
+ ## ⚑ Key Features
87
+
88
+ - πŸ”Œ **Dynamic Multi-MCP Tool Orchestration** β€” Aggregate custom Python functions, external FastMCP servers, and cloud services into schema-validated, discoverable tool sets with automatic LLM tool routing.
89
+ - πŸ•ΈοΈ **Hybrid RAG (Vector + Knowledge Graph)** β€” Dual-channel retrieval engine pairing semantic vector search (ChromaDB, Qdrant, FastEmbed) with relation-aware multi-hop graph queries (NetworkX, Neo4j).
90
+ - 🧠 **Model Agnostic Inference** β€” Native support for offline local LLMs via **Ollama** (Qwen 2.5, Llama 3, Mistral) and frontier cloud models (**Google Gemini**, **OpenAI**, Groq, vLLM) with zero lock-in.
91
+ - πŸ“Š **Real-Time Interactive Inspector** β€” Built-in dashboard at `/inspector` to test prompts, monitor live tool execution traces, inspect retrieved vector chunks, and explore relation facts.
92
+ - 🌐 **3D WebGL Knowledge Graph** β€” Standalone interactive visualizer at `/graph/export` featuring physics simulations, entity clustering, and real-time relation navigation.
93
+ - πŸ“¦ **One-Click MCP Server Export** β€” Expose your application's tools to Claude Desktop, Cursor, or LibreChat with `synapse export-mcp`.
94
+ - πŸ›‘οΈ **Zero Vulnerabilities & High Test Coverage** β€” Clean 100% Bandit security audit, full type annotations, and modern Python 3.10+ async architecture.
95
+
96
+ ---
97
+
98
+ ## πŸ“Έ Interactive Inspector & 3D Graph
99
+
100
+ ### 1. Developer Inspector Dashboard (`/inspector`)
101
+ Test chat prompts, observe schema-validated tool invocations in real time, and audit retrieved vector chunks and knowledge graph triples side-by-side:
102
+
103
+ <p align="center">
104
+ <img src="assets/inspector_preview.png" width="100%" alt="Synapse Inspector Dashboard" style="border-radius: 12px; border: 1px solid #27272a; box-shadow: 0 8px 24px rgba(0,0,0,0.5);"/>
105
+ </p>
106
+
107
+ ### 2. 3D WebGL Knowledge Graph Explorer (`/graph/export`)
108
+ Navigate and visualize complex entity relationships and multi-hop triples in an interactive 3D physics-based canvas:
109
+
110
+ <p align="center">
111
+ <img src="assets/graph_preview.png" width="100%" alt="Synapse 3D Knowledge Graph" style="border-radius: 12px; border: 1px solid #27272a; box-shadow: 0 8px 24px rgba(0,0,0,0.5);"/>
112
+ </p>
113
+
114
+ ### 3. Connector & Sync Manager (`/connectors`)
115
+ Audit connected tools, check authentication status, and trigger on-demand synchronization:
116
+
117
+ <p align="center">
118
+ <img src="assets/connectors_preview.png" width="100%" alt="Synapse Connectors View" style="border-radius: 12px; border: 1px solid #27272a; box-shadow: 0 8px 24px rgba(0,0,0,0.5);"/>
119
+ </p>
120
+
121
+ ### 4. Interactive OpenAPI & Swagger Endpoints (`/docs`)
122
+ Explore and test all REST routes, SSE streams, sync triggers, and MCP export endpoints in real time:
123
+
124
+ <p align="center">
125
+ <img src="assets/openapi_preview.png" width="100%" alt="Synapse OpenAPI Docs" style="border-radius: 12px; border: 1px solid #27272a; box-shadow: 0 8px 24px rgba(0,0,0,0.5);"/>
126
+ </p>
127
+
128
+ ---
129
+
130
+ ## πŸ—οΈ Core Architecture
131
+
132
+ ```mermaid
133
+ flowchart TD
134
+ subgraph Clients ["Clients & Interfaces"]
135
+ UI["Web Inspector (/inspector)"]
136
+ CLI["Cursor / Claude Desktop (MCP)"]
137
+ API["REST & SSE Endpoints (/chat)"]
138
+ end
139
+
140
+ subgraph Core ["Synapse BaseApp Engine"]
141
+ Router["FastAPI Application"]
142
+ Dispatcher["Tool & Skill Dispatcher"]
143
+ Context["Execution Tracer"]
144
+ end
145
+
146
+ subgraph LLM ["Model Providers"]
147
+ OLL["Ollama (Qwen, Llama 3)"]
148
+ GEM["Google Gemini 1.5 / 2.0"]
149
+ OAI["OpenAI (GPT-4o, mini)"]
150
+ end
151
+
152
+ subgraph Storage ["Hybrid RAG & Memory"]
153
+ Vec["Vector Store (ChromaDB / Qdrant)"]
154
+ Graph["Knowledge Graph (NetworkX / Neo4j)"]
155
+ Emb["Local Embeddings (FastEmbed / BGE)"]
156
+ end
157
+
158
+ subgraph Tools ["Multi-MCP Connectors"]
159
+ F1["Custom Tools (makeconnectors)"]
160
+ F2["OAuth Connectors (Gmail, Notion, Photos)"]
161
+ F3["External FastMCP Servers"]
162
+ end
163
+
164
+ UI --> Router
165
+ CLI --> Router
166
+ API --> Router
167
+
168
+ Router --> Dispatcher
169
+ Dispatcher <--> LLM
170
+ Dispatcher <--> Storage
171
+ Dispatcher <--> Tools
172
+ Dispatcher --> Context
173
+ ```
174
+
175
+ ---
176
+
177
+ ## πŸ“¦ Installation
178
+
179
+ Install `synapse-framework` using pip:
180
+
181
+ ```bash
182
+ pip install synapse-framework
183
+ ```
184
+
185
+ Or using `uv`:
186
+
187
+ ```bash
188
+ uv add synapse-framework
189
+ ```
190
+
191
+ ### Optional Extras
192
+
193
+ ```bash
194
+ # Add Qdrant vector database support
195
+ pip install "synapse-framework[qdrant]"
196
+
197
+ # Install all optional drivers and dependencies
198
+ pip install "synapse-framework[all]"
199
+ ```
200
+
201
+ ---
202
+
203
+ ## πŸš€ 60-Second Quickstart
204
+
205
+ Create an intelligent assistant with custom Python tools, local Ollama inference, and a live web inspector in under 25 lines of code:
206
+
207
+ ```python
208
+ from typing import Dict, Any
209
+ from synapse import BaseApp
210
+ from synapse.models import Ollama
211
+ from synapse.connectors import makeconnectors
212
+
213
+ # 1. Define custom tools with clear docstrings
214
+ def search_product_catalog(query: str, category: str = "all") -> Dict[str, Any]:
215
+ """Searches the product database and inventory across warehouses."""
216
+ return {"results": [{"id": "SKU-992", "name": "Neuro-Link Adapter", "price": 149.0, "stock": 42}]}
217
+
218
+ def calculate_shipping(weight_kg: float, international: bool = False) -> Dict[str, Any]:
219
+ """Calculates shipping cost based on package weight and destination."""
220
+ rate = 14.5 if international else 5.5
221
+ return {"cost_usd": round(weight_kg * rate, 2), "carrier": "Express Air"}
222
+
223
+ # 2. Package tools into an MCP connector
224
+ inventory_connector = makeconnectors(
225
+ name="inventory_service",
226
+ tools=[search_product_catalog, calculate_shipping],
227
+ )
228
+
229
+ # 3. Initialize Synapse application
230
+ app = BaseApp(
231
+ title="Logistics Assistant",
232
+ model=Ollama(model="qwen2.5:0.5b", base_url="http://localhost:11434"),
233
+ connectors=[inventory_connector],
234
+ visualize_graph=True,
235
+ )
236
+
237
+ if __name__ == "__main__":
238
+ app.run(host="127.0.0.1", port=8000)
239
+ ```
240
+
241
+ Open your browser to start interacting:
242
+ - πŸ“Š **Web Inspector**: [`http://127.0.0.1:8000/inspector`](http://127.0.0.1:8000/inspector)
243
+ - πŸ•ΈοΈ **3D Knowledge Graph**: [`http://127.0.0.1:8000/graph/export`](http://127.0.0.1:8000/graph/export)
244
+ - πŸ“– **Interactive OpenAPI Docs**: [`http://127.0.0.1:8000/docs`](http://127.0.0.1:8000/docs)
245
+
246
+ ---
247
+
248
+ ## 🧠 Pluggable Model Providers
249
+
250
+ Synapse offers unified model abstractions with automatic prompt formatting and tool calling normalization:
251
+
252
+ ### 1. Local Ollama (Offline / Private)
253
+ ```python
254
+ from synapse.models import Ollama
255
+
256
+ model = Ollama(
257
+ model="qwen2.5:0.5b",
258
+ base_url="http://localhost:11434",
259
+ temperature=0.2,
260
+ )
261
+ ```
262
+
263
+ ### 2. Google Gemini
264
+ ```python
265
+ import os
266
+ from synapse.models import Gemini
267
+
268
+ model = Gemini(
269
+ api_key=os.getenv("GEMINI_API_KEY"),
270
+ model="gemini-1.5-flash",
271
+ )
272
+ ```
273
+
274
+ ### 3. OpenAI / Groq / OpenRouter / vLLM
275
+ ```python
276
+ import os
277
+ from synapse.models import OpenAI
278
+
279
+ model = OpenAI(
280
+ api_key=os.getenv("OPENAI_API_KEY"),
281
+ model="gpt-4o-mini",
282
+ )
283
+ ```
284
+
285
+ ---
286
+
287
+ ## πŸ”Œ Connectors & Custom Tools
288
+
289
+ ### Custom Tools via `makeconnectors`
290
+ Transform any Python functions into a tool connector ready for MCP client consumption:
291
+
292
+ ```python
293
+ from synapse.connectors import makeconnectors
294
+
295
+ def query_financial_metrics(quarter: str = "Q3") -> dict:
296
+ """Returns quarterly revenue, operating expenses, and net profit margin."""
297
+ return {"revenue": 420000, "expenses": 180000, "margin": "57.1%"}
298
+
299
+ finance_connector = makeconnectors(
300
+ name="finance_analytics",
301
+ tools=[query_financial_metrics],
302
+ )
303
+ ```
304
+
305
+ ### Prebuilt OAuth Productivity Connectors
306
+ Synapse includes managed OAuth 2.0 lifecycle helpers:
307
+
308
+ ```python
309
+ from synapse.oauth import GoogleOAuthService
310
+ from synapse.connectors import GmailConnectors, GooglePhotosConnectors, NotionConnectors
311
+
312
+ oauth = GoogleOAuthService(
313
+ credentials_path="credentials.json",
314
+ token_path="token.json",
315
+ )
316
+
317
+ gmail = GmailConnectors(oauth_service=oauth)
318
+ photos = GooglePhotosConnectors(oauth_service=oauth)
319
+ notion = NotionConnectors(api_key="secret_notion_key")
320
+ ```
321
+
322
+ ---
323
+
324
+ ## πŸ•ΈοΈ Hybrid RAG & Knowledge Graph
325
+
326
+ Synapse pairs dense semantic similarity with relational graph reasoning:
327
+
328
+ ```python
329
+ from synapse.storage import PersistentGraphStore, VectorStore
330
+ from synapse.rag import HybridRAG
331
+
332
+ # 1. Initialize persistent storage layers
333
+ graph_store = PersistentGraphStore(filepath="./data/graph.json")
334
+ vector_store = VectorStore(persist_dir="./data/chroma_db")
335
+
336
+ # 2. Add relational facts to knowledge graph
337
+ graph_store.add_relation("Alice", "LEADS", "Platform Engineering", source_type="Person", target_type="Organization")
338
+ graph_store.add_relation("Platform Engineering", "MAINTAINS", "Synapse Framework", source_type="Organization", target_type="Project")
339
+
340
+ # 3. Query combined knowledge base
341
+ rag = HybridRAG(vector_store=vector_store, graph_store=graph_store)
342
+ result = rag.retrieve_context("What does Alice lead?")
343
+
344
+ print("Entities found:", result["entities_detected"])
345
+ print("Graph facts:", result["graph_facts"])
346
+ ```
347
+
348
+ ---
349
+
350
+ ## 🌐 API Endpoint Reference
351
+
352
+ Synapse automatically mounts standard REST, Server-Sent Events (SSE), and documentation endpoints on your application:
353
+
354
+ | Method | Endpoint | Tag | Description |
355
+ | :--- | :--- | :--- | :--- |
356
+ | `GET` | **`/`** or **`/inspector`** | `Inspector` | Interactive Web Inspector dashboard for chat, trace inspection, and tools. |
357
+ | `POST` | **`/chat`** | `Chat` | Server-Sent Events (SSE) streaming endpoint for agent prompts, tool calls, and grounded replies. |
358
+ | `GET` | **`/graph/export`** | `Graph` | Full-screen interactive 3D WebGL knowledge graph visualizer. |
359
+ | `GET` | **`/graph/data`** | `Graph` | JSON payload containing all graph nodes, directed links, color tokens, and stats. |
360
+ | `GET` | **`/connectors`** | `Sync` | Lists all registered connectors, descriptions, and active tools. |
361
+ | `POST` | **`/sync/{connector_name}`** | `Sync` | Triggers background synchronization and indexing for a specific connector. |
362
+ | `GET` | **`/sync/status`** | `Sync` | Returns current synchronization progress, item counts, and timestamps. |
363
+ | `GET` | **`/mcp/export`** | `MCP` | Exports active tools into Claude Desktop config format and FastMCP manifests. |
364
+ | `GET` | **`/skills`** | `Skills` | Returns registered agent skills and specialized system instructions. |
365
+ | `GET` | **`/resources`** | `Resources` | Lists static reference documents and indexed data resources. |
366
+ | `GET` | **`/info`** | `Inspector` | Overview of running model provider, connector count, and framework version. |
367
+ | `GET` | **`/health`** | `System` | Health check endpoint returning status and uptime. |
368
+ | `GET` | **`/docs`** | `Docs` | Interactive Swagger / OpenAPI documentation with try-it-out capabilities. |
369
+
370
+ ---
371
+
372
+ ## πŸ› οΈ Claude Desktop & Cursor Export
373
+
374
+ Export your application tools directly to Claude Desktop or Cursor:
375
+
376
+ ```bash
377
+ # Export config file
378
+ synapse export-mcp --output claude_desktop_config.json
379
+ ```
380
+
381
+ Add the configuration block into your `claude_desktop_config.json`:
382
+
383
+ ```json
384
+ {
385
+ "mcpServers": {
386
+ "synapse": {
387
+ "command": "python",
388
+ "args": ["-m", "synapse.export.mcp_server", "--port", "8000"]
389
+ }
390
+ }
391
+ }
392
+ ```
393
+
394
+ ---
395
+
396
+ ## πŸ§ͺ Testing & Code Quality
397
+
398
+ Synapse is built with strict code quality and security verification:
399
+
400
+ ```bash
401
+ # Run pytest test suite (23 unit tests)
402
+ pytest tests/
403
+
404
+ # Run security static analysis (0 vulnerabilities)
405
+ bandit -r synapse
406
+
407
+ # Check code formatting and modern standards
408
+ ruff check synapse/
409
+ ```
410
+
411
+ ---
412
+
413
+ ## πŸ“„ License
414
+
415
+ Synapse is licensed under the [MIT License](LICENSE).