fairo 25.8.1__tar.gz → 25.9.1__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.
Potentially problematic release.
This version of fairo might be problematic. Click here for more details.
- {fairo-25.8.1 → fairo-25.9.1}/PKG-INFO +1 -3
- fairo-25.9.1/fairo/__init__.py +1 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/chat/chat.py +6 -10
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/execution/executor.py +29 -6
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/workflow/dependency.py +11 -146
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/workflow/utils.py +29 -1
- {fairo-25.8.1 → fairo-25.9.1}/fairo.egg-info/PKG-INFO +1 -3
- {fairo-25.8.1 → fairo-25.9.1}/fairo.egg-info/requires.txt +0 -2
- {fairo-25.8.1 → fairo-25.9.1}/pyproject.toml +0 -2
- fairo-25.8.1/fairo/__init__.py +0 -1
- {fairo-25.8.1 → fairo-25.9.1}/README.md +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/base_agent.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/code_analysis_agent.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/output/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/output/base_output.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/output/google_drive.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/tools/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/tools/base_tools.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/tools/code_analysis.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/tools/utils.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/agent/utils.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/chat/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/client/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/client/client.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/exceptions.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/execution/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/execution/agent_serializer.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/execution/env_finder.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/execution/model_log_helper.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/models/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/models/custom_field_value.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/models/resources.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/runnable/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/runnable/runnable.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/workflow/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/core/workflow/base_workflow.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/metrics/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/metrics/fairness_object.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/metrics/metrics.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/settings.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/tests/__init__.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo/tests/test_metrics.py +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo.egg-info/SOURCES.txt +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo.egg-info/dependency_links.txt +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/fairo.egg-info/top_level.txt +0 -0
- {fairo-25.8.1 → fairo-25.9.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fairo
|
|
3
|
-
Version: 25.
|
|
3
|
+
Version: 25.9.1
|
|
4
4
|
Summary: SDK for interfacing with Fairo SaaS platform.
|
|
5
5
|
Author-email: "Fairo Systems, Inc." <support@fairo.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -17,8 +17,6 @@ Requires-Dist: langchain-aws<0.3.0,>=0.2.18
|
|
|
17
17
|
Requires-Dist: langchain-community<0.4.0,>=0.3.20
|
|
18
18
|
Requires-Dist: langchain-core<0.4.0,>=0.3.49
|
|
19
19
|
Requires-Dist: langchain-text-splitters<0.4.0,>=0.3.7
|
|
20
|
-
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0
|
|
21
|
-
Requires-Dist: langchain-postgres<0.1.0,>=0.0.14
|
|
22
20
|
Requires-Dist: setuptools>=79.0.0
|
|
23
21
|
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
24
22
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "25.9.1"
|
|
@@ -31,10 +31,10 @@ class FairoDeploymentClient(BaseDeploymentClient):
|
|
|
31
31
|
|
|
32
32
|
# Add authentication if needed
|
|
33
33
|
auth = None
|
|
34
|
-
if os.environ.get('
|
|
34
|
+
if os.environ.get('FAIRO_API_ACCESS_KEY_ID') and os.environ.get('FAIRO_API_SECRET'):
|
|
35
35
|
auth = HTTPBasicAuth(
|
|
36
|
-
os.environ.get('
|
|
37
|
-
os.environ.get('
|
|
36
|
+
os.environ.get('FAIRO_API_ACCESS_KEY_ID'),
|
|
37
|
+
os.environ.get('FAIRO_API_SECRET')
|
|
38
38
|
)
|
|
39
39
|
|
|
40
40
|
# Make streaming request
|
|
@@ -116,10 +116,10 @@ class FairoDeploymentClient(BaseDeploymentClient):
|
|
|
116
116
|
|
|
117
117
|
# Add authentication if needed
|
|
118
118
|
auth = None
|
|
119
|
-
if os.environ.get('
|
|
119
|
+
if os.environ.get('FAIRO_API_ACCESS_KEY_ID') and os.environ.get('FAIRO_API_SECRET'):
|
|
120
120
|
auth = HTTPBasicAuth(
|
|
121
|
-
os.environ.get('
|
|
122
|
-
os.environ.get('
|
|
121
|
+
os.environ.get('FAIRO_API_ACCESS_KEY_ID'),
|
|
122
|
+
os.environ.get('FAIRO_API_SECRET')
|
|
123
123
|
)
|
|
124
124
|
|
|
125
125
|
if os.environ.get('MLFLOW_TRACKING_TOKEN'):
|
|
@@ -183,10 +183,6 @@ class ChatFairo(ChatMlflow):
|
|
|
183
183
|
|
|
184
184
|
def __init__(self, **kwargs):
|
|
185
185
|
|
|
186
|
-
# # TODO <- see if this can be improved
|
|
187
|
-
# os.environ["MLFLOW_TRACKING_USERNAME"] = get_mlflow_user()
|
|
188
|
-
# os.environ["MLFLOW_TRACKING_PASSWORD"] = get_mlflow_password()
|
|
189
|
-
|
|
190
186
|
super().__init__(
|
|
191
187
|
target_uri=os.environ.get('MLFLOW_GATEWAY_URI', get_mlflow_gateway_uri()),
|
|
192
188
|
endpoint=os.environ.get('MLFLOW_GATEWAY_ROUTE', get_mlflow_gateway_chat_route()),
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
|
-
from typing import List, Any, Callable, Dict, Union
|
|
3
|
+
from typing import List, Any, Callable, Dict, Optional, Type, Union
|
|
4
4
|
from langchain_core.runnables import RunnableLambda, RunnableSequence
|
|
5
5
|
from langchain.chains import SimpleSequentialChain
|
|
6
6
|
import logging
|
|
7
7
|
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
8
10
|
import mlflow
|
|
9
11
|
|
|
10
12
|
from mlflow.models.signature import ModelSignature
|
|
@@ -32,11 +34,13 @@ class FairoExecutor:
|
|
|
32
34
|
experiment_name: str = None,
|
|
33
35
|
chain_class = SimpleSequentialChain,
|
|
34
36
|
input_fields: List[str] = [],
|
|
37
|
+
input_schema: Optional[Type[BaseModel]] = None,
|
|
35
38
|
):
|
|
36
39
|
if agents and runnable:
|
|
37
40
|
raise ValueError("FairoExecutor cannot be initialized with both 'agents' and 'runnable'. Please provide only one.")
|
|
38
|
-
if not input_fields:
|
|
39
|
-
raise ValueError("Missing input_fields")
|
|
41
|
+
if not input_fields and not input_schema:
|
|
42
|
+
raise ValueError("Missing required parameters: please provide at least one of 'input_fields' or 'input_schema'")
|
|
43
|
+
self.input_schema = input_schema
|
|
40
44
|
self.agents = agents
|
|
41
45
|
self.agent_type = agent_type
|
|
42
46
|
self.verbose = verbose
|
|
@@ -67,8 +71,26 @@ class FairoExecutor:
|
|
|
67
71
|
pipeline = mlflow.pyfunc.load_model(self.runnable.artifact_path)
|
|
68
72
|
else:
|
|
69
73
|
pipeline = AgentChainWrapper(chain_class=self.chain_class, agent_functions_list=self.agents)
|
|
70
|
-
|
|
71
|
-
input_schema
|
|
74
|
+
# Convert Pydantic schema to MLflow Schema
|
|
75
|
+
if hasattr(self.input_schema, 'model_json_schema'):
|
|
76
|
+
# Extract field names from Pydantic schema
|
|
77
|
+
pydantic_schema = self.input_schema.model_json_schema()
|
|
78
|
+
properties = pydantic_schema.get('properties', {})
|
|
79
|
+
cols = []
|
|
80
|
+
for field_name, field_info in properties.items():
|
|
81
|
+
field_type = field_info.get('type', 'string')
|
|
82
|
+
# Map Pydantic types to MLflow types
|
|
83
|
+
mlflow_type = 'string' # Default to string
|
|
84
|
+
if field_type in ['integer', 'number']:
|
|
85
|
+
mlflow_type = 'double'
|
|
86
|
+
elif field_type == 'boolean':
|
|
87
|
+
mlflow_type = 'boolean'
|
|
88
|
+
cols.append(ColSpec(type=mlflow_type, name=field_name))
|
|
89
|
+
input_schema = Schema(cols)
|
|
90
|
+
else:
|
|
91
|
+
# Fallback to input_fields if schema is not Pydantic
|
|
92
|
+
cols = [ColSpec(type="string", name=field) for field in self.input_fields]
|
|
93
|
+
input_schema = Schema(cols)
|
|
72
94
|
|
|
73
95
|
output_schema = Schema([
|
|
74
96
|
ColSpec(type="string", name="output"),
|
|
@@ -97,7 +119,8 @@ class FairoExecutor:
|
|
|
97
119
|
fairo_settings = {
|
|
98
120
|
"type": type,
|
|
99
121
|
"process_graph": process_graph,
|
|
100
|
-
"
|
|
122
|
+
"schema": self.input_schema.model_json_schema() if self.input_schema else None,
|
|
123
|
+
"input_fields": list(self.input_schema.model_fields.keys()) if self.input_schema else self.input_fields,
|
|
101
124
|
}
|
|
102
125
|
if process_graph:
|
|
103
126
|
mlflow.log_text(json.dumps(fairo_settings, ensure_ascii=False, indent=2), artifact_file="fairo_settings.txt")
|
|
@@ -1,155 +1,16 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import Any, Dict, List, Optional, Tuple
|
|
3
|
-
from langchain_aws import BedrockEmbeddings
|
|
4
3
|
from langchain_community.embeddings.mlflow import MlflowEmbeddings
|
|
5
4
|
from langchain_core.documents import Document
|
|
6
|
-
from
|
|
7
|
-
from fairo.settings import get_mlflow_gateway_embeddings_route, get_mlflow_gateway_uri
|
|
5
|
+
from fairo.settings import get_mlflow_gateway_embeddings_route, get_mlflow_gateway_uri, get_fairo_api_key, get_fairo_api_secret, get_fairo_base_url
|
|
8
6
|
from fairo.core.client.client import BaseClient
|
|
9
|
-
AWS_AI_EMBEDDING_MODEL = 'cohere.embed-english-v3'
|
|
10
7
|
import requests
|
|
11
|
-
|
|
8
|
+
AWS_AI_EMBEDDING_MODEL = 'cohere.embed-english-v3'
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
class BaseVectorStore:
|
|
15
12
|
pass
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
class PostgresVectorStore(BaseVectorStore):
|
|
19
|
-
"""
|
|
20
|
-
A PostgreSQL-based vector store using LangChain and pgvector
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def __init__(
|
|
24
|
-
self,
|
|
25
|
-
collection_name: str,
|
|
26
|
-
embedding_model_id: str = AWS_AI_EMBEDDING_MODEL,
|
|
27
|
-
region_name: str = None,
|
|
28
|
-
collection_metadata: dict = None,
|
|
29
|
-
connection_string: str = "postgresql://postgres:postgres@localhost:5432/vectordb",
|
|
30
|
-
pre_delete_collection: bool = False,
|
|
31
|
-
default_k: int = 5
|
|
32
|
-
):
|
|
33
|
-
"""
|
|
34
|
-
Args:
|
|
35
|
-
collection_name: Name of the collection in PostgreSQL
|
|
36
|
-
embedding_model_id: Bedrock embedding model ID
|
|
37
|
-
region_name: AWS region for Bedrock
|
|
38
|
-
collection_metadata: Dict for what metadata we want to add to collection
|
|
39
|
-
connection_string: PostgreSQL connection string
|
|
40
|
-
"""
|
|
41
|
-
self.collection_name = collection_name
|
|
42
|
-
self.connection_string = connection_string
|
|
43
|
-
|
|
44
|
-
# Set up embeddings
|
|
45
|
-
self.embeddings = MlflowEmbeddings(
|
|
46
|
-
target_uri=get_mlflow_gateway_uri(),
|
|
47
|
-
endpoint=get_mlflow_gateway_embeddings_route(),
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
if collection_metadata is not None:
|
|
51
|
-
self.collection_metadata = collection_metadata
|
|
52
|
-
|
|
53
|
-
# Initialize the PGVector store
|
|
54
|
-
self.db = PGVector(
|
|
55
|
-
collection_name=collection_name,
|
|
56
|
-
connection=connection_string,
|
|
57
|
-
collection_metadata=self.collection_metadata,
|
|
58
|
-
embeddings=self.embeddings,
|
|
59
|
-
pre_delete_collection=pre_delete_collection
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
self.default_k = default_k
|
|
63
|
-
|
|
64
|
-
def add_documents(self, documents: List[Document]) -> None:
|
|
65
|
-
"""
|
|
66
|
-
Args:
|
|
67
|
-
documents: List of Document objects to add
|
|
68
|
-
"""
|
|
69
|
-
if not documents:
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
# Add documents to PGVector
|
|
73
|
-
self.db.add_documents(documents)
|
|
74
|
-
|
|
75
|
-
def add_texts(self, texts: List[str], metadatas: Optional[List[Dict[str, Any]]] = None) -> None:
|
|
76
|
-
"""
|
|
77
|
-
Args:
|
|
78
|
-
texts: List of text strings to add
|
|
79
|
-
metadatas: Optional list of metadata dictionaries
|
|
80
|
-
"""
|
|
81
|
-
if not texts:
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
# Convert to Document objects
|
|
85
|
-
documents = []
|
|
86
|
-
for i, text in enumerate(texts):
|
|
87
|
-
metadata = metadatas[i] if metadatas and i < len(metadatas) else {}
|
|
88
|
-
documents.append(Document(page_content=text, metadata=metadata))
|
|
89
|
-
|
|
90
|
-
# Add to vector store
|
|
91
|
-
self.add_documents(documents)
|
|
92
|
-
|
|
93
|
-
@staticmethod
|
|
94
|
-
def _format_query(query):
|
|
95
|
-
# Temporary fix, need to consider model / do more than truncate
|
|
96
|
-
return query[0:2048]
|
|
97
|
-
|
|
98
|
-
def similarity_search(self, query: str, k: int = None) -> List[Document]:
|
|
99
|
-
"""
|
|
100
|
-
Args:
|
|
101
|
-
query: The search query
|
|
102
|
-
k: Number of results to return
|
|
103
|
-
"""
|
|
104
|
-
formatted_query = self._format_query(query)
|
|
105
|
-
if k is None:
|
|
106
|
-
k = self.default_k
|
|
107
|
-
return self.db.similarity_search(formatted_query, k=k)
|
|
108
|
-
|
|
109
|
-
def similarity_search_with_score(self, query: str, k: int = 4) -> List[tuple[Document, float]]:
|
|
110
|
-
"""
|
|
111
|
-
Args:
|
|
112
|
-
query: The search query
|
|
113
|
-
k: Number of results to return
|
|
114
|
-
"""
|
|
115
|
-
formatted_query = self._format_query(query)
|
|
116
|
-
if k is None:
|
|
117
|
-
k = self.default_k
|
|
118
|
-
return self.db.similarity_search_with_score(formatted_query, k=k)
|
|
119
|
-
|
|
120
|
-
def delete(self) -> None:
|
|
121
|
-
"""Delete the collection from PostgreSQL."""
|
|
122
|
-
try:
|
|
123
|
-
# Use the internal PGVector method to delete a collection
|
|
124
|
-
self.db._client.delete_collection(self.collection_name)
|
|
125
|
-
except Exception as e:
|
|
126
|
-
print(f"Error deleting collection: {str(e)}")
|
|
127
|
-
|
|
128
|
-
@classmethod
|
|
129
|
-
def from_existing(cls,
|
|
130
|
-
collection_name: str,
|
|
131
|
-
embedding_model_id: str = AWS_AI_EMBEDDING_MODEL,
|
|
132
|
-
region_name: str = None,
|
|
133
|
-
connection_string: str = "postgresql://postgres:postgres@localhost:5432/vectordb"):
|
|
134
|
-
"""
|
|
135
|
-
Load an existing collection from PostgreSQL.
|
|
136
|
-
|
|
137
|
-
Args:
|
|
138
|
-
collection_name: Name of the existing collection
|
|
139
|
-
embedding_model_id: Bedrock embedding model ID
|
|
140
|
-
region_name: AWS region for Bedrock
|
|
141
|
-
connection_string: PostgreSQL connection string
|
|
142
|
-
|
|
143
|
-
Returns:
|
|
144
|
-
PostgresVectorStore instance connected to the existing collection
|
|
145
|
-
"""
|
|
146
|
-
return cls(
|
|
147
|
-
collection_name=collection_name,
|
|
148
|
-
embedding_model_id=embedding_model_id,
|
|
149
|
-
region_name=region_name,
|
|
150
|
-
connection_string=connection_string
|
|
151
|
-
)
|
|
152
|
-
|
|
153
14
|
class FairoVectorStore(BaseVectorStore):
|
|
154
15
|
"""
|
|
155
16
|
A vector store implementation using the Fairo API
|
|
@@ -182,14 +43,18 @@ class FairoVectorStore(BaseVectorStore):
|
|
|
182
43
|
self.collection_name = collection_name
|
|
183
44
|
|
|
184
45
|
# Get credentials from parameters or environment
|
|
185
|
-
self.username = username or
|
|
186
|
-
self.password = password or
|
|
187
|
-
self.api_url = api_url or
|
|
46
|
+
self.username = username or get_fairo_api_key()
|
|
47
|
+
self.password = password or get_fairo_api_secret()
|
|
48
|
+
self.api_url = api_url or get_fairo_base_url()
|
|
188
49
|
self.fairo_auth_token = os.environ.get("FAIRO_AUTH_TOKEN")
|
|
189
|
-
|
|
50
|
+
# Setup credentials
|
|
190
51
|
if not self.fairo_auth_token and (not self.username or not self.password):
|
|
191
52
|
raise ValueError("Fairo API credentials must be provided either as FAIRO_AUTH_TOKEN or as parameters or in the FAIRO_USERNAME and FAIRO_PASSWORD environment variables")
|
|
192
53
|
|
|
54
|
+
if(self.username and self.password):
|
|
55
|
+
os.environ["MLFLOW_TRACKING_USERNAME"] = self.username
|
|
56
|
+
os.environ["MLFLOW_TRACKING_PASSWORD"] = self.password
|
|
57
|
+
|
|
193
58
|
# Initialize API client
|
|
194
59
|
self.client = BaseClient(
|
|
195
60
|
base_url=self.api_url.rstrip('/'),
|
|
@@ -429,7 +294,7 @@ class FairoVectorStore(BaseVectorStore):
|
|
|
429
294
|
collection_name: str,
|
|
430
295
|
username: str = None,
|
|
431
296
|
password: str = None,
|
|
432
|
-
api_url: str =
|
|
297
|
+
api_url: str = get_fairo_base_url(),
|
|
433
298
|
embedding_model_id: str = AWS_AI_EMBEDDING_MODEL,
|
|
434
299
|
region_name: str = None):
|
|
435
300
|
"""
|
|
@@ -278,6 +278,7 @@ def output_langchain_process_graph(agents):
|
|
|
278
278
|
"prompt": get_agent_prompt(agent),
|
|
279
279
|
"prefix": agent_kwargs.get("prefix", ""),
|
|
280
280
|
"suffix": agent_kwargs.get("suffix", ""),
|
|
281
|
+
"schema": get_agent_schema(agent),
|
|
281
282
|
}
|
|
282
283
|
)
|
|
283
284
|
|
|
@@ -457,4 +458,31 @@ def get_agent_prompt(agent) -> str:
|
|
|
457
458
|
search_queue.append(child)
|
|
458
459
|
|
|
459
460
|
# Nothing found – return empty string
|
|
460
|
-
return ""
|
|
461
|
+
return ""
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def get_agent_schema(agent):
|
|
465
|
+
"""
|
|
466
|
+
Returns a JSON schema dict when available, otherwise None.
|
|
467
|
+
Checks common attributes across SimpleAgent and LangChain agents.
|
|
468
|
+
"""
|
|
469
|
+
candidate_attrs = ("args_schema", "input_schema", "agent_schema", "schema")
|
|
470
|
+
for attr in candidate_attrs:
|
|
471
|
+
obj = getattr(agent, attr, None)
|
|
472
|
+
if obj is None:
|
|
473
|
+
continue
|
|
474
|
+
try:
|
|
475
|
+
if isinstance(obj, dict):
|
|
476
|
+
return obj
|
|
477
|
+
if hasattr(obj, "model_json_schema") and callable(getattr(obj, "model_json_schema")):
|
|
478
|
+
return obj.model_json_schema()
|
|
479
|
+
if hasattr(obj, "schema") and callable(getattr(obj, "schema")):
|
|
480
|
+
return obj.schema()
|
|
481
|
+
except Exception as e:
|
|
482
|
+
pass
|
|
483
|
+
|
|
484
|
+
inner = getattr(agent, "agent", None)
|
|
485
|
+
if inner is not None and inner is not agent:
|
|
486
|
+
return get_agent_schema(inner)
|
|
487
|
+
|
|
488
|
+
return None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fairo
|
|
3
|
-
Version: 25.
|
|
3
|
+
Version: 25.9.1
|
|
4
4
|
Summary: SDK for interfacing with Fairo SaaS platform.
|
|
5
5
|
Author-email: "Fairo Systems, Inc." <support@fairo.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -17,8 +17,6 @@ Requires-Dist: langchain-aws<0.3.0,>=0.2.18
|
|
|
17
17
|
Requires-Dist: langchain-community<0.4.0,>=0.3.20
|
|
18
18
|
Requires-Dist: langchain-core<0.4.0,>=0.3.49
|
|
19
19
|
Requires-Dist: langchain-text-splitters<0.4.0,>=0.3.7
|
|
20
|
-
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0
|
|
21
|
-
Requires-Dist: langchain-postgres<0.1.0,>=0.0.14
|
|
22
20
|
Requires-Dist: setuptools>=79.0.0
|
|
23
21
|
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
24
22
|
|
|
@@ -26,8 +26,6 @@ dependencies = [
|
|
|
26
26
|
"langchain-community>=0.3.20,<0.4.0",
|
|
27
27
|
"langchain-core>=0.3.49,<0.4.0",
|
|
28
28
|
"langchain-text-splitters>=0.3.7,<0.4.0",
|
|
29
|
-
"psycopg2-binary>=2.9.0,<3.0.0",
|
|
30
|
-
"langchain-postgres>=0.0.14,<0.1.0",
|
|
31
29
|
"setuptools>=79.0.0",
|
|
32
30
|
"pandas>=2.0.0,<3.0.0"
|
|
33
31
|
]
|
fairo-25.8.1/fairo/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "25.8.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|