modaic 0.1.0__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.

Potentially problematic release.


This version of modaic might be problematic. Click here for more details.

Files changed (39) hide show
  1. modaic/__init__.py +25 -0
  2. modaic/agents/rag_agent.py +33 -0
  3. modaic/agents/registry.py +84 -0
  4. modaic/auto_agent.py +228 -0
  5. modaic/context/__init__.py +34 -0
  6. modaic/context/base.py +1064 -0
  7. modaic/context/dtype_mapping.py +25 -0
  8. modaic/context/table.py +585 -0
  9. modaic/context/text.py +94 -0
  10. modaic/databases/__init__.py +35 -0
  11. modaic/databases/graph_database.py +269 -0
  12. modaic/databases/sql_database.py +355 -0
  13. modaic/databases/vector_database/__init__.py +12 -0
  14. modaic/databases/vector_database/benchmarks/baseline.py +123 -0
  15. modaic/databases/vector_database/benchmarks/common.py +48 -0
  16. modaic/databases/vector_database/benchmarks/fork.py +132 -0
  17. modaic/databases/vector_database/benchmarks/threaded.py +119 -0
  18. modaic/databases/vector_database/vector_database.py +722 -0
  19. modaic/databases/vector_database/vendors/milvus.py +408 -0
  20. modaic/databases/vector_database/vendors/mongodb.py +0 -0
  21. modaic/databases/vector_database/vendors/pinecone.py +0 -0
  22. modaic/databases/vector_database/vendors/qdrant.py +1 -0
  23. modaic/exceptions.py +38 -0
  24. modaic/hub.py +305 -0
  25. modaic/indexing.py +127 -0
  26. modaic/module_utils.py +341 -0
  27. modaic/observability.py +275 -0
  28. modaic/precompiled.py +429 -0
  29. modaic/query_language.py +321 -0
  30. modaic/storage/__init__.py +3 -0
  31. modaic/storage/file_store.py +239 -0
  32. modaic/storage/pickle_store.py +25 -0
  33. modaic/types.py +287 -0
  34. modaic/utils.py +21 -0
  35. modaic-0.1.0.dist-info/METADATA +281 -0
  36. modaic-0.1.0.dist-info/RECORD +39 -0
  37. modaic-0.1.0.dist-info/WHEEL +5 -0
  38. modaic-0.1.0.dist-info/licenses/LICENSE +31 -0
  39. modaic-0.1.0.dist-info/top_level.txt +1 -0
modaic/types.py ADDED
@@ -0,0 +1,287 @@
1
+ from typing import Any, List, Literal, Optional, Tuple, Type, get_origin
2
+
3
+ from pydantic import (
4
+ BaseModel,
5
+ RootModel,
6
+ WithJsonSchema,
7
+ field_validator,
8
+ model_validator,
9
+ )
10
+ from pydantic import (
11
+ Field as PydanticField,
12
+ )
13
+ from pydantic.fields import FieldInfo
14
+ from pydantic_core import PydanticUndefined
15
+ from typing_extensions import Annotated
16
+
17
+ from .exceptions import SchemaError
18
+
19
+ int8 = Annotated[
20
+ int,
21
+ PydanticField(ge=-128, le=127),
22
+ WithJsonSchema({"type": "integer", "format": "int8"}),
23
+ ]
24
+ int16 = Annotated[
25
+ int,
26
+ PydanticField(ge=-32768, le=32767),
27
+ WithJsonSchema({"type": "integer", "format": "int16"}),
28
+ ]
29
+ int32 = Annotated[
30
+ int,
31
+ PydanticField(ge=-(2**31), le=2**31 - 1),
32
+ WithJsonSchema({"type": "integer", "format": "int32"}),
33
+ ]
34
+ int64 = Annotated[
35
+ int,
36
+ PydanticField(ge=-(2**63), le=2**63 - 1),
37
+ WithJsonSchema({"type": "integer", "format": "int64"}),
38
+ ]
39
+ double = Annotated[
40
+ float,
41
+ PydanticField(ge=-1.87e308, le=1.87e308),
42
+ WithJsonSchema({"type": "number", "format": "double"}),
43
+ ]
44
+
45
+
46
+ class ArrayMeta(type):
47
+ def __getitem__(cls, params: type | tuple[type, int]):
48
+ if isinstance(params, tuple) and len(params) == 2:
49
+ dtype = params[0]
50
+ max_size = params[1]
51
+ elif isinstance(params, type) or get_origin(params) is Annotated:
52
+ dtype = params
53
+ max_size = None
54
+ else:
55
+ raise TypeError(
56
+ f"{cls.__name__} requires either 2 parameters: {cls.__name__}[dtype, max_size] or 1 parameter: {cls.__name__}[dtype]"
57
+ )
58
+
59
+ assert isinstance(dtype, type) or get_origin(dtype) is Annotated, f"dtype must be a type, got {dtype}"
60
+ assert max_size is None or (isinstance(max_size, int) and max_size > 0), (
61
+ f"max_size must be an int or None, got {max_size}"
62
+ )
63
+
64
+ return Annotated[
65
+ List[dtype],
66
+ PydanticField(min_length=0, max_length=max_size),
67
+ ]
68
+
69
+
70
+ class Array(List, metaclass=ArrayMeta):
71
+ """
72
+ Array field type for `Context`. Must be created with Array[dtype, max_size]
73
+
74
+ Args:
75
+ dtype (Type): The type of the elements in the array.
76
+ max_size (int): The maximum size of the array.
77
+
78
+ Example:
79
+ A `Email` context class that stores an email's content and recipients.
80
+ ```python
81
+ from modaic.types import Array
82
+ from modaic.context import Context
83
+
84
+ class Email(Context):
85
+ content: str
86
+ recipients: Array[str, 100]
87
+ ```
88
+ """
89
+
90
+ pass
91
+
92
+
93
+ class StringMeta(type):
94
+ def __getitem__(cls, params: int):
95
+ if not isinstance(params, int):
96
+ raise TypeError(f"{cls.__name__} requires exactly 1 parameters: {cls.__name__}[max_size]")
97
+
98
+ max_size = params
99
+ if not isinstance(max_size, int) or max_size <= 1:
100
+ raise TypeError(f"Max size must be a >= 1, got {max_size}")
101
+
102
+ return Annotated[
103
+ str,
104
+ PydanticField(max_length=max_size),
105
+ WithJsonSchema({"type": "string", "maxLength": max_size}),
106
+ ]
107
+
108
+
109
+ class String(str, metaclass=StringMeta):
110
+ """String type that can be parameterized with max_length constraint.
111
+
112
+ Args:
113
+ max_size (int): The maximum length of the string.
114
+
115
+ Example:
116
+ ```python
117
+ from modaic.types import String
118
+ from modaic.context import Context
119
+
120
+ class Email(Context):
121
+ subject: String[100]
122
+ content: str
123
+ recipients: Array[str, 100]
124
+ ```
125
+ """
126
+
127
+ pass
128
+
129
+
130
+ def fetch_type(metadata: list, type_class: Type) -> Optional[Type]:
131
+ return next((x for x in metadata if isinstance(x, type_class)), None)
132
+
133
+
134
+ def get_original_class(field_info: FieldInfo, default: Optional[Type] = None) -> Type:
135
+ if json_schema_extra := getattr(field_info, "json_schema_extra", None):
136
+ return json_schema_extra.get("original_class", default)
137
+ return default
138
+
139
+
140
+ int_format = Literal["int8", "int16", "int32", "int64"]
141
+ float_format = Literal["float", "double"]
142
+
143
+
144
+ class SchemaField(BaseModel):
145
+ optional: bool
146
+ type: Literal["array", "integer", "number", "object", "string", "boolean"]
147
+ format: int_format | float_format | None
148
+ size: Optional[int]
149
+ inner_type: Optional["InnerField"]
150
+ is_id: bool = False
151
+ is_unique: bool = False
152
+
153
+ @model_validator(mode="after")
154
+ def validate_field(self) -> "SchemaField":
155
+ if self.type == "array" and self.inner_type is None:
156
+ raise SchemaError("Array type must have an inner type")
157
+ if self.is_id and not self.is_unique:
158
+ raise SchemaError("id field must be unique")
159
+ if self.is_id and self.optional:
160
+ raise SchemaError("id field cannot be optional")
161
+ if self.is_id and self.type != "string":
162
+ raise SchemaError("id field must be a string")
163
+ # NOTE: handle case where the float type was used and therefore not annotated with a format
164
+ if self.type == "number":
165
+ self.format = self.format or "float"
166
+ return self
167
+
168
+ @staticmethod
169
+ def from_json_schema_property(
170
+ field_schema: dict, is_id: bool = False, is_unique: Optional[bool] = None
171
+ ) -> "SchemaField":
172
+ inspected_type, is_optional = _inspect_type(field_schema)
173
+ if "maxItems" in inspected_type and "maxLength" in inspected_type:
174
+ raise SchemaError("maxItems and maxLength cannot both be present in a schema field")
175
+ if "items" in inspected_type:
176
+ inner_type = InnerField.from_json_schema_property(inspected_type["items"])
177
+ else:
178
+ inner_type = None
179
+ if is_unique is None:
180
+ is_unique = is_id
181
+
182
+ return SchemaField(
183
+ optional=is_optional,
184
+ type=inspected_type["type"],
185
+ format=inspected_type.get("format", None),
186
+ size=inspected_type.get("maxItems", None) or inspected_type.get("maxLength", None),
187
+ inner_type=inner_type,
188
+ is_id=is_id,
189
+ is_unique=is_unique,
190
+ )
191
+
192
+
193
+ class InnerField(BaseModel):
194
+ type: Literal["integer", "number", "string", "boolean"]
195
+ format: int_format | float_format | None = None
196
+ size: Optional[int] = None
197
+
198
+ @model_validator(mode="after")
199
+ def validate_field(self) -> "InnerField":
200
+ if self.type == "number":
201
+ self.format = self.format or "float"
202
+ return self
203
+
204
+ @staticmethod
205
+ def from_json_schema_property(inner_schema: dict) -> "InnerField":
206
+ inspected_type, is_optional = _inspect_type(inner_schema)
207
+ # NOTE: handle case where the float type was used and therefore not annotated with a format
208
+ if is_optional:
209
+ raise SchemaError("Array/List elements cannot be None/null")
210
+ return InnerField(
211
+ type=inspected_type["type"],
212
+ format=inspected_type.get("format", None),
213
+ size=inspected_type.get("size", None),
214
+ )
215
+
216
+
217
+ class Schema(RootModel[dict[str, SchemaField]]):
218
+ @field_validator("root")
219
+ @classmethod
220
+ def validate_is_id(cls, v: dict[str, SchemaField]) -> dict[str, SchemaField]:
221
+ offenders = [k for k, sf in v.items() if sf.is_id and k != "id"]
222
+ if offenders:
223
+ raise SchemaError(
224
+ "is_id can only be True for the key 'id'; offending keys: " + ", ".join(repr(k) for k in offenders)
225
+ )
226
+ return v
227
+
228
+ @staticmethod
229
+ def from_json_schema(schema: dict) -> "Schema":
230
+ """
231
+ Converts an OpenAPI JSON schema to a Modaic schema that can be used with modaic databases.
232
+ Warnings:
233
+ Not designed to handle all edge cases of OpenAPI schemas. Only designed to work with jsons output by pydantics BaseModel model_json_schema()
234
+ """
235
+ validated_fields = {}
236
+ for field_name, field_schema in schema["properties"].items():
237
+ schema_field = SchemaField.from_json_schema_property(field_schema, is_id=field_name == "id")
238
+ validated_fields[field_name] = schema_field
239
+ return Schema(validated_fields)
240
+
241
+ def as_dict(self) -> dict[str, SchemaField]:
242
+ return self.root
243
+
244
+
245
+ def _inspect_type(field_schema: dict) -> Tuple[dict, bool]:
246
+ """
247
+ This function inspects the json schema ensuring it is a valid modaic schema. Returns from this function are guaranteed to:
248
+ 1. Be a dictionary containing the key "type"
249
+ 2. Not have unions other than a single union with null
250
+ 3. All {"$ref": "..."} is replaced with {"type": "object"}
251
+ Returns:
252
+ Tuple[dict, bool]: the dict containing the type, and a boolean indicating if the field is optional
253
+ """
254
+ if anyOf := field_schema.get("anyOf", None): # noqa: N806
255
+ if len(anyOf) > 2 or not any(_is_null(item) for item in anyOf):
256
+ raise SchemaError("Unions are not supported for Modaic Schemas")
257
+ elif any(not _is_null(type_ := item) for item in anyOf):
258
+ return _handle_if_ref(type_), True
259
+ else:
260
+ raise SchemaError("Invalid field schema")
261
+ elif "type" in field_schema:
262
+ return _handle_if_ref(field_schema), False
263
+ elif "$ref" in field_schema:
264
+ return {"type": "object"}, False
265
+ else:
266
+ raise SchemaError("Invalid field schema")
267
+
268
+
269
+ def _handle_if_ref(field_schema: dict) -> dict:
270
+ """
271
+ Handles the case where the field is a reference to another schema. Returns an {"type": "object"}
272
+ """
273
+ if "$ref" in field_schema:
274
+ return {"type": "object"}
275
+ else:
276
+ return field_schema
277
+
278
+
279
+ def _is_null(field_schema: dict) -> bool:
280
+ return field_schema.get("type", "") == "null"
281
+
282
+
283
+ def Field(default: Any = PydanticUndefined, *, hidden: bool = False, **kwargs) -> FieldInfo: # noqa: N802, ANN001
284
+ if hidden:
285
+ return PydanticField(default=default, **kwargs, json_schema_extra={"hidden": True})
286
+ else:
287
+ return PydanticField(default=default, **kwargs)
modaic/utils.py ADDED
@@ -0,0 +1,21 @@
1
+ import os
2
+ import re
3
+ from pathlib import Path
4
+
5
+ from dotenv import load_dotenv
6
+
7
+ load_dotenv()
8
+
9
+
10
+ def compute_cache_dir() -> Path:
11
+ """Return the cache directory used to stage internal modules."""
12
+ cache_dir_env = os.getenv("MODAIC_CACHE")
13
+ default_cache_dir = Path(os.path.expanduser("~")) / ".cache" / "modaic"
14
+ cache_dir = Path(cache_dir_env).expanduser().resolve() if cache_dir_env else default_cache_dir.resolve()
15
+ cache_dir.mkdir(parents=True, exist_ok=True)
16
+ return cache_dir
17
+
18
+
19
+ def validate_project_name(text: str) -> bool:
20
+ """Letters, numbers, underscore, hyphen"""
21
+ assert bool(re.match(r'^[a-zA-Z0-9_]+$', text)), "Invalid project name. Must contain only letters, numbers, and underscore."
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.4
2
+ Name: modaic
3
+ Version: 0.1.0
4
+ Summary: **Mod**ular **A**gent **I**nfrastructure **C**ollective, a python framework for managing and sharing DSPy agents
5
+ Author-email: Tyrin <tytodd@mit.edu>, Farouk <farouk@modaic.dev>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Modaic Inc
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ ---
29
+
30
+ Additional Terms:
31
+
32
+ 1. You may not modify this Software in any way that changes the default hub
33
+ endpoint, nor distribute derivative works that route agents or models to
34
+ a hub other than modaic.dev.
35
+
36
+ 2. All other rights are granted as per the MIT License.
37
+
38
+ Requires-Python: >=3.10
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: aenum>=3.1.16
42
+ Requires-Dist: dspy>=2.6.27
43
+ Requires-Dist: duckdb>=1.3.2
44
+ Requires-Dist: filetype>=1.2.0
45
+ Requires-Dist: gitpython>=3.1.45
46
+ Requires-Dist: immutables>=0.21
47
+ Requires-Dist: langchain-community>=0.3.29
48
+ Requires-Dist: langchain-core>=0.3.72
49
+ Requires-Dist: langchain-text-splitters>=0.3.9
50
+ Requires-Dist: more-itertools>=10.8.0
51
+ Requires-Dist: opik>=1.8.42
52
+ Requires-Dist: pillow>=11.3.0
53
+ Requires-Dist: pymilvus>=2.5.14
54
+ Requires-Dist: sqlalchemy>=2.0.42
55
+ Requires-Dist: tomlkit>=0.13.3
56
+ Provides-Extra: pinecone
57
+ Requires-Dist: pinecone>=7.3.0; extra == "pinecone"
58
+ Dynamic: license-file
59
+
60
+ [![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://docs.modaic.dev)
61
+ # Modaic 🐙
62
+ **Mod**ular **A**gent **I**nfrastructure **C**ollective, a Python framework for building AI agents with structured context management, database integration, and retrieval-augmented generation (RAG) capabilities.
63
+
64
+ ## Overview
65
+
66
+ Modaic provides a comprehensive toolkit for creating intelligent agents that can work with diverse data sources including tables, documents, and databases. Built on top of DSPy, it offers a way to share and manage declarative agent architectures with integrated vector, SQL, and graph database support.
67
+
68
+ ## Key Features
69
+
70
+ - **Hub Support**: Load and share precompiled agents from Modaic Hub
71
+ - **Context Management**: Structured handling of molecular and atomic context types
72
+ - **Database Integration**: Support for Vector (Milvus, Pinecone, Qdrant), SQL (SQLite, MySQL, PostgreSQL), and Graph (Memgraph, Neo4j)
73
+ - **Agent Framework**: Precompiled and auto-loading agent architectures
74
+ - **Table Processing**: Advanced Excel/CSV processing with SQL querying capabilities
75
+
76
+
77
+ ## Installation
78
+
79
+ ### Using uv (recommended)
80
+
81
+ ```bash
82
+ uv add modaic
83
+ ```
84
+
85
+ Optional (for hub operations):
86
+
87
+ ```bash
88
+ export MODAIC_TOKEN="<your-token>"
89
+ ```
90
+
91
+ ### Using pip
92
+ Please note that you will not be able to push agents to the Modaic Hub with pip.
93
+ ```bash
94
+ pip install modaic
95
+ ```
96
+ ## Quick Start
97
+
98
+ ### Creating a Simple Agent
99
+
100
+ ```python
101
+ from modaic import PrecompiledAgent, PrecompiledConfig
102
+
103
+ class WeatherConfig(PrecompiledConfig):
104
+ weather: str = "sunny"
105
+
106
+ class WeatherAgent(PrecompiledAgent):
107
+ config: WeatherConfig
108
+
109
+ def __init__(self, config: WeatherConfig, **kwargs):
110
+ super().__init__(config, **kwargs)
111
+
112
+ def forward(self, query: str) -> str:
113
+ return f"The weather in {query} is {self.config.weather}."
114
+
115
+ agent = WeatherAgent(WeatherConfig())
116
+ print(agent(query="Tokyo"))
117
+ ```
118
+
119
+ Save and load locally:
120
+
121
+ ```python
122
+ agent.save_precompiled("./my-weather")
123
+
124
+ from modaic import AutoAgent, AutoConfig
125
+
126
+ cfg = AutoConfig.from_precompiled("./my-weather", local=True)
127
+ loaded = AutoAgent.from_precompiled("./my-weather", local=True)
128
+ print(loaded(query="Kyoto"))
129
+ ```
130
+
131
+ ### Working with Tables
132
+
133
+ ```python
134
+ from pathlib import Path
135
+ from modaic.context import Table, TableFile
136
+ import pandas as pd
137
+
138
+ # Load from Excel/CSV
139
+ excel = TableFile.from_file(
140
+ file_ref="employees.xlsx",
141
+ file=Path("employees.xlsx"),
142
+ file_type="xlsx",
143
+ )
144
+ csv = TableFile.from_file(
145
+ file_ref="data.csv",
146
+ file=Path("data.csv"),
147
+ file_type="csv",
148
+ )
149
+
150
+ # Create from DataFrame
151
+ df = pd.DataFrame({"col1": [1, 2, 3], "col2": [4, 5, 6]})
152
+ table = Table(df=df, name="my_table")
153
+
154
+ # Query with SQL (refer to in-memory table as `this`)
155
+ result = table.query("SELECT * FROM this WHERE col1 > 1")
156
+
157
+ # Convert to markdown
158
+ markdown = table.markdown()
159
+ ```
160
+
161
+ ### Database Integration
162
+
163
+ #### SQL Database
164
+ ```python
165
+ from modaic.databases import SQLDatabase, SQLiteBackend
166
+
167
+ # Configure and connect
168
+ backend = SQLiteBackend(db_path="my_database.db")
169
+ db = SQLDatabase(backend)
170
+
171
+ # Add table
172
+ db.add_table(table)
173
+
174
+ # Query
175
+ rows = db.fetchall("SELECT * FROM my_table")
176
+ ```
177
+
178
+ #### Vector Database
179
+ #### Graph Database
180
+ ```python
181
+ from modaic.context import Context, Relation
182
+ from modaic.databases import GraphDatabase, MemgraphConfig, Neo4jConfig
183
+
184
+ # Configure backend (choose one)
185
+ mg = GraphDatabase(MemgraphConfig())
186
+ # or
187
+ neo = GraphDatabase(Neo4jConfig())
188
+
189
+ # Define nodes
190
+ class Person(Context):
191
+ name: str
192
+ age: int
193
+
194
+ class KNOWS(Relation):
195
+ since: int
196
+
197
+ alice = Person(name="Alice", age=30)
198
+ bob = Person(name="Bob", age=28)
199
+
200
+ # Save nodes
201
+ alice.save(mg)
202
+ bob.save(mg)
203
+
204
+ # Create relationship (Alice)-[KNOWS]->(Bob)
205
+ rel = (alice >> KNOWS(since=2020) >> bob)
206
+ rel.save(mg)
207
+
208
+ # Query
209
+ rows = mg.execute_and_fetch("MATCH (a:Person)-[r:KNOWS]->(b:Person) RETURN a, r, b LIMIT 5")
210
+ ```
211
+ ```python
212
+ from modaic import Embedder
213
+ from modaic.context import Text
214
+ from modaic.databases import VectorDatabase, MilvusBackend
215
+
216
+ # Setup embedder and backend
217
+ embedder = Embedder("openai/text-embedding-3-small")
218
+ backend = MilvusBackend.from_local("vector.db") # milvus lite
219
+
220
+ # Initialize database
221
+ vdb = VectorDatabase(backend=backend, embedder=embedder, payload_class=Text)
222
+
223
+ # Create collection and add records
224
+ vdb.create_collection("my_collection", payload_class=Text)
225
+ vdb.add_records("my_collection", [Text(text="hello world"), Text(text="modaic makes sharing agents easy")])
226
+
227
+ # Search
228
+ results = vdb.search("my_collection", query="hello", k=3)
229
+ top_hit_text = results[0][0].context.text
230
+ ```
231
+
232
+ ## Architecture
233
+ ### Agent Types
234
+
235
+ 1. **PrecompiledAgent**: Statically defined agents with explicit configuration
236
+ 2. **AutoAgent**: Dynamically loaded agents from Modaic Hub or local repositories
237
+
238
+ ### Database Support
239
+
240
+ | Database Type | Providers | Use Case |
241
+ |---------------|-----------|----------|
242
+ | **Vector** | Milvus | Semantic search, RAG |
243
+ | **SQL** | SQLite, MySQL, PostgreSQL | Structured queries, table storage |
244
+
245
+ ## Examples
246
+
247
+ ### TableRAG Example
248
+
249
+ The TableRAG example demonstrates a complete RAG pipeline for table-based question answering:
250
+
251
+ ```python
252
+ from modaic.precompiled_agent import PrecompiledConfig, PrecompiledAgent
253
+ from modaic.context import Table
254
+ from modaic.databases import VectorDatabase, SQLDatabase
255
+ from modaic.types import Indexer
256
+
257
+ class TableRAGConfig(PrecompiledConfig):
258
+ agent_type = "TableRAGAgent"
259
+ k_recall: int = 50
260
+ k_rerank: int = 5
261
+
262
+ class TableRAGAgent(PrecompiledAgent):
263
+ config: TableRAGConfig # ! Important: config must be annotated with the config class
264
+
265
+ def __init__(self, config: TableRAGConfig, indexer: Indexer, **kwargs):
266
+ super().__init__(config, **kwargs)
267
+ self.indexer = indexer
268
+ # Initialize DSPy modules for reasoning
269
+
270
+ def forward(self, user_query: str) -> str:
271
+ # Retrieve relevant tables
272
+ # Generate SQL queries
273
+ # Combine results and provide answer
274
+ pass
275
+ ```
276
+
277
+ ## Support
278
+
279
+ For issues and questions:
280
+ - GitHub Issues: `https://github.com/modaic-ai/modaic/issues`
281
+ - Docs: `https://docs.modaic.dev`
@@ -0,0 +1,39 @@
1
+ modaic/__init__.py,sha256=rf2O0S7OAz5fBkmOcwygsM3u8Nmq_ios01ToNweNnSk,639
2
+ modaic/auto_agent.py,sha256=jegs8HMbE5OICZIDtBrP4kIma_R7rzy-1Kgmb_-eCck,8695
3
+ modaic/exceptions.py,sha256=XxzxOWjZTzT3l1BqTr7coJnVGxJq53uppRNrqP__YGo,651
4
+ modaic/hub.py,sha256=iWvWjaZxurd2BRXTS2gjhBvqVE1TDtwF0N7Falwj04Q,10527
5
+ modaic/indexing.py,sha256=L0O5yV7AhDUJ0gMyGE17BvHN2gwHxwkOMaxNTkyWQ8g,4185
6
+ modaic/module_utils.py,sha256=DDXUmcGFdaah_EhTlfdHC26ohmMwLNlIYo6PzYzKzqc,10728
7
+ modaic/observability.py,sha256=QEjLbmsVQzWZuxKQU8TBMSHsHVGvTzOeoNlEn_srmyg,9955
8
+ modaic/precompiled.py,sha256=g0AsFrHxzTlDETDqxZFqjHaLqW6m5OpGGyI01xDBT5U,15788
9
+ modaic/query_language.py,sha256=c-La7jYhHgNyjlQaxz0ALvUoiCDGzH9DpSD_9cozxNQ,10463
10
+ modaic/types.py,sha256=sHJ7J9YGfWIkDPfCuRc-n4O9n7g7LNnKSZperAviRFc,9905
11
+ modaic/utils.py,sha256=zbeMlrP_hoo8JUKR_bcuYPxrlYcckY3p0KJ_h4CN5VQ,721
12
+ modaic/agents/rag_agent.py,sha256=f8s3EILOPUxMpOKDoAvk-cfLE8S9kFNvkEcAC5z2EmQ,798
13
+ modaic/agents/registry.py,sha256=z6GuPxGrq2dinCamiMJ_HVPsD9Tp9XWDUSMZ-uhWPrU,2446
14
+ modaic/context/__init__.py,sha256=WTBo-WqhgeR84P3MEq0snLZyIHnLyv9VYO5Wfp4vrZo,534
15
+ modaic/context/base.py,sha256=QrRNBs05fb5EXN4intHT4D-XIG76RzvrO6j8RXJpzd4,40380
16
+ modaic/context/dtype_mapping.py,sha256=xRasW-H92YEuOfH8SbsVnodM9F-90pazott8qF2GWHw,519
17
+ modaic/context/table.py,sha256=c0OUVwglaDRtJ2Uo9z7bAKhIJpJXqwWk1VkKwQNOvUY,17696
18
+ modaic/context/text.py,sha256=S8E-dbTe-Wip8KCZ5vcIOZVyiVQReIL4bSo0anQw828,2581
19
+ modaic/databases/__init__.py,sha256=-w_yiY-Sqi1SgcPD5oAQL7MU4VXTihPa1GYGlrHfsFw,784
20
+ modaic/databases/graph_database.py,sha256=vMCYQrnBu5AIIGF_akkU9lWKFdbIDF3tlcyxiNQ_vSQ,9933
21
+ modaic/databases/sql_database.py,sha256=wqy7AqsalhmYsbNPy0FCAg1FrUKN6Bd8ytwyJireC94,12057
22
+ modaic/databases/vector_database/__init__.py,sha256=sN1SuSAMC9NHJDOa80BN_olccaHgmiW2Ek57hBvdZWo,306
23
+ modaic/databases/vector_database/vector_database.py,sha256=RsuRemgFV06opY26CekqLLRoAEFYOGl_CMuFETrYS0c,25238
24
+ modaic/databases/vector_database/benchmarks/baseline.py,sha256=ZhiYzHnizsLesAIQA93RhWaaYxEZp6ygExmnBhU9Dio,5209
25
+ modaic/databases/vector_database/benchmarks/common.py,sha256=fgPfnv1P55YAB5S6mORIpDMtKymsCPBjuQNiO5qLbJQ,1386
26
+ modaic/databases/vector_database/benchmarks/fork.py,sha256=Q-2dnsxB4_28mfkGHS2Y9-f-Fksym1bbdTFP-r0AKTk,5566
27
+ modaic/databases/vector_database/benchmarks/threaded.py,sha256=s2s1GwIRYq9oon5nsF_DRa65leCYc5uws6a5oHijk1M,5195
28
+ modaic/databases/vector_database/vendors/milvus.py,sha256=YT6rhRhe4bEC3lsgddno8k6wi1HqawqhvXXVkNYs3pY,15732
29
+ modaic/databases/vector_database/vendors/mongodb.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ modaic/databases/vector_database/vendors/pinecone.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ modaic/databases/vector_database/vendors/qdrant.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
32
+ modaic/storage/__init__.py,sha256=Zs-Y_9jfYUE8XVp8z-El0ZXFM_ZVMqM9aQ6fgGPZsf8,131
33
+ modaic/storage/file_store.py,sha256=kSS7gTP_-16wR3Xgq3frF1BZ8Dw8N--kG4V9rrCXPcc,7315
34
+ modaic/storage/pickle_store.py,sha256=fu9jkmmKNE852Y4R1NhOFePLfd2gskhHSXxuq1G1S3I,778
35
+ modaic-0.1.0.dist-info/licenses/LICENSE,sha256=7LMx9j453Vz1DoQbFot8Uhp9SExF5wlOx7c8vw2qhsE,1333
36
+ modaic-0.1.0.dist-info/METADATA,sha256=9Q1xSwbRGQl6GKKm32POVFdBlprvBCCcKxtNsVMKFFM,8585
37
+ modaic-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
+ modaic-0.1.0.dist-info/top_level.txt,sha256=RXWGuF-TsW8-17DveTJMPRiAgg_Rf2mq5F3R7tNu6t8,7
39
+ modaic-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,31 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Modaic Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Additional Terms:
26
+
27
+ 1. You may not modify this Software in any way that changes the default hub
28
+ endpoint, nor distribute derivative works that route agents or models to
29
+ a hub other than modaic.dev.
30
+
31
+ 2. All other rights are granted as per the MIT License.
@@ -0,0 +1 @@
1
+ modaic