fairo 25.5.4__tar.gz → 25.6.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (45) hide show
  1. {fairo-25.5.4 → fairo-25.6.2}/PKG-INFO +1 -1
  2. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/base_agent.py +25 -26
  3. fairo-25.6.2/fairo/core/chat/chat.py +23 -0
  4. fairo-25.6.2/fairo/core/execution/env_finder.py +46 -0
  5. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/execution/executor.py +107 -15
  6. fairo-25.6.2/fairo/core/runnable/runnable.py +77 -0
  7. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/workflow/base_workflow.py +3 -2
  8. fairo-25.6.2/fairo/metrics/__init__.py +0 -0
  9. {fairo-25.5.4 → fairo-25.6.2}/fairo/settings.py +2 -0
  10. fairo-25.6.2/fairo/tests/__init__.py +0 -0
  11. {fairo-25.5.4 → fairo-25.6.2}/fairo.egg-info/PKG-INFO +1 -1
  12. {fairo-25.5.4 → fairo-25.6.2}/fairo.egg-info/SOURCES.txt +5 -0
  13. {fairo-25.5.4 → fairo-25.6.2}/README.md +0 -0
  14. {fairo-25.5.4 → fairo-25.6.2}/fairo/__init__.py +0 -0
  15. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/__init__.py +0 -0
  16. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/__init__.py +0 -0
  17. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/code_analysis_agent.py +0 -0
  18. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/output/__init__.py +0 -0
  19. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/output/base_output.py +0 -0
  20. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/output/google_drive.py +0 -0
  21. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/tools/__init__.py +0 -0
  22. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/tools/base_tools.py +0 -0
  23. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/tools/code_analysis.py +0 -0
  24. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/tools/utils.py +0 -0
  25. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/agent/utils.py +0 -0
  26. {fairo-25.5.4/fairo/core/client → fairo-25.6.2/fairo/core/chat}/__init__.py +0 -0
  27. {fairo-25.5.4/fairo/core/execution → fairo-25.6.2/fairo/core/client}/__init__.py +0 -0
  28. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/client/client.py +0 -0
  29. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/exceptions.py +0 -0
  30. {fairo-25.5.4/fairo/core/models → fairo-25.6.2/fairo/core/execution}/__init__.py +0 -0
  31. {fairo-25.5.4/fairo/core/workflow → fairo-25.6.2/fairo/core/models}/__init__.py +0 -0
  32. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/models/custom_field_value.py +0 -0
  33. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/models/resources.py +0 -0
  34. {fairo-25.5.4/fairo/metrics → fairo-25.6.2/fairo/core/runnable}/__init__.py +0 -0
  35. {fairo-25.5.4/fairo/tests → fairo-25.6.2/fairo/core/workflow}/__init__.py +0 -0
  36. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/workflow/dependency.py +0 -0
  37. {fairo-25.5.4 → fairo-25.6.2}/fairo/core/workflow/utils.py +0 -0
  38. {fairo-25.5.4 → fairo-25.6.2}/fairo/metrics/fairness_object.py +0 -0
  39. {fairo-25.5.4 → fairo-25.6.2}/fairo/metrics/metrics.py +0 -0
  40. {fairo-25.5.4 → fairo-25.6.2}/fairo/tests/test_metrics.py +0 -0
  41. {fairo-25.5.4 → fairo-25.6.2}/fairo.egg-info/dependency_links.txt +0 -0
  42. {fairo-25.5.4 → fairo-25.6.2}/fairo.egg-info/requires.txt +0 -0
  43. {fairo-25.5.4 → fairo-25.6.2}/fairo.egg-info/top_level.txt +0 -0
  44. {fairo-25.5.4 → fairo-25.6.2}/pyproject.toml +0 -0
  45. {fairo-25.5.4 → fairo-25.6.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fairo
3
- Version: 25.5.4
3
+ Version: 25.6.2
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
@@ -8,12 +8,12 @@ import sys
8
8
  from typing import Dict, List, Optional, Callable, Any, Tuple
9
9
  from langchain.schema import HumanMessage, AIMessage, SystemMessage
10
10
  from langchain_core.messages import ToolMessage
11
- from langchain_community.chat_models.mlflow import ChatMlflow
12
11
  from langchain_core.runnables.config import RunnableConfig
13
12
  from fairo.core.agent.output.base_output import BaseOutput
14
13
  from fairo.core.agent.tools.base_tools import BaseTool
15
14
  from fairo.core.agent.tools.utils import Iteration, LLMAgentOutput, ToolResult
16
15
  from langchain_core.messages.tool import ToolCall
16
+ from fairo.core.chat.chat import FairoChat
17
17
  from fairo.core.client.client import BaseClient
18
18
  from fairo.core.workflow.dependency import BaseVectorStore
19
19
  from fairo.core.agent.utils import truncate_content, truncate_obj_content
@@ -66,10 +66,9 @@ class SimpleAgent:
66
66
  self.verbose = verbose
67
67
  self.use_langchain_mlflow_chat = True if not llm else False
68
68
  self.workflow_run_id = workflow_run_id
69
- self.llm = llm or ChatMlflow(
70
- target_uri=get_mlflow_gateway_uri(),
69
+ self.llm = llm or FairoChat(
71
70
  endpoint=get_mlflow_gateway_chat_route(),
72
- extra_params={"workflow_run_id": self.workflow_run_id}
71
+ workflow_run_id=self.workflow_run_id
73
72
  )
74
73
  self.memory = memory or []
75
74
  self.conversation_history = []
@@ -782,12 +781,12 @@ class SimpleAgent:
782
781
  output.add_duration(f"{total_execution_time:.2f}s")
783
782
 
784
783
  # Save output
785
- if self.patch_run_output_json:
786
- self.patch_run_output_json(output.to_dict())
784
+ # if self.patch_run_output_json:
785
+ # self.patch_run_output_json(output.to_dict())
787
786
 
788
787
  # Execute output
789
- if self.output and len(self.output) > 0:
790
- self.execute_outputs(final_answer)
788
+ # if self.output and len(self.output) > 0:
789
+ # self.execute_outputs(final_answer)
791
790
 
792
791
  return final_answer
793
792
 
@@ -823,8 +822,8 @@ class SimpleAgent:
823
822
  output.add_duration(f"{total_execution_time:.2f}s")
824
823
 
825
824
  # Make sure to patch the output with the error
826
- if self.patch_run_output_json:
827
- self.patch_run_output_json(output.to_dict())
825
+ # if self.patch_run_output_json:
826
+ # self.patch_run_output_json(output.to_dict())
828
827
 
829
828
  # Re-throw the exception with more context
830
829
  raise Exception(f"Agent execution failed: {error_msg}") from e
@@ -855,22 +854,22 @@ class SimpleAgent:
855
854
  output_errors.append((error_msg, traceback_details))
856
855
 
857
856
  # Report errors after processing all outputs to avoid multiple error records for the same run
858
- if output_errors and self.patch_run_output_json:
859
- # Create a single error output object with all errors
860
- error_output = LLMAgentOutput(
861
- node_name=self.agent_name,
862
- task="Output execution",
863
- context=None,
864
- query_result=None,
865
- memory=None
866
- )
867
-
868
- # Add all collected errors
869
- for error_msg, traceback_details in output_errors:
870
- error_output.add_error(error_msg, traceback_details)
871
-
872
- # Patch once with all errors
873
- self.patch_run_output_json(error_output.to_dict())
857
+ # if output_errors and self.patch_run_output_json:
858
+ # # Create a single error output object with all errors
859
+ # error_output = LLMAgentOutput(
860
+ # node_name=self.agent_name,
861
+ # task="Output execution",
862
+ # context=None,
863
+ # query_result=None,
864
+ # memory=None
865
+ # )
866
+
867
+ # # Add all collected errors
868
+ # for error_msg, traceback_details in output_errors:
869
+ # error_output.add_error(error_msg, traceback_details)
870
+
871
+ # # Patch once with all errors
872
+ # self.patch_run_output_json(error_output.to_dict())
874
873
 
875
874
  def add_memory(self, content: str) -> None:
876
875
  """
@@ -0,0 +1,23 @@
1
+
2
+ from langchain_community.chat_models.mlflow import ChatMlflow
3
+ from mlflow.deployments import get_deploy_client
4
+ import os
5
+
6
+ class FairoChat(ChatMlflow):
7
+ def __init__(self, endpoint, workflow_run_id, **kwargs):
8
+ super().__init__(
9
+ target_uri=os.environ.get('MLFLOW_GATEWAY_URI', None),
10
+ endpoint=endpoint,
11
+ extra_params={"workflow_run_id": workflow_run_id},
12
+ **kwargs
13
+ )
14
+
15
+ @property
16
+ def _target_uri(self):
17
+ return os.environ.get("MLFLOW_GATEWAY_URI", None)
18
+
19
+ def invoke(self, *args, **kwargs):
20
+ # Override invoke to use dynamic target_uri
21
+ self.target_uri = self._target_uri
22
+ self._client = get_deploy_client(self.target_uri)
23
+ return super().invoke(*args, **kwargs)
@@ -0,0 +1,46 @@
1
+ import os
2
+ import re
3
+ import mlflow
4
+
5
+ ENV_PATTERNS = [
6
+ re.compile(r"os\.getenv\(\s*[\"'](\w+)[\"']"), # os.getenv("VAR")
7
+ re.compile(r"os\.environ\.get\(\s*[\"'](\w+)[\"']"), # os.environ.get("VAR")
8
+ re.compile(r"os\.environ\[\s*[\"'](\w+)[\"']\s*\]"), # os.environ["VAR"]
9
+ ]
10
+
11
+ def find_env_vars_in_file(file_path):
12
+ found_vars = set()
13
+ try:
14
+ with open(file_path, "r", encoding="utf-8") as f:
15
+ content = f.read()
16
+ for pattern in ENV_PATTERNS:
17
+ found_vars.update(pattern.findall(content))
18
+ except (UnicodeDecodeError, OSError):
19
+ pass # Skip unreadable files
20
+ return found_vars
21
+
22
+ def recursively_find_env_vars(start_path, exclude_dirs=None):
23
+ if exclude_dirs is None:
24
+ exclude_dirs = {"venv", ".venv", "__pycache__", ".git", ".mypy_cache", ".pytest_cache", "site-packages"}
25
+
26
+ all_vars = set()
27
+ for root, dirs, files in os.walk(start_path):
28
+ # Skip excluded directories
29
+ dirs[:] = [d for d in dirs if d not in exclude_dirs and not d.startswith(".")]
30
+
31
+ for file in files:
32
+ if file.endswith(".py"):
33
+ full_path = os.path.join(root, file)
34
+ file_vars = find_env_vars_in_file(full_path)
35
+ if file_vars:
36
+ print(f"Found in {full_path}: {file_vars}")
37
+ all_vars.update(file_vars)
38
+ return all_vars
39
+
40
+ def read_variables() -> str:
41
+ current_path = os.getcwd()
42
+ env_vars = recursively_find_env_vars(current_path)
43
+ logged_vars = ""
44
+ for var in env_vars:
45
+ logged_vars += f"{var}\n"
46
+ return logged_vars
@@ -1,42 +1,55 @@
1
+ import json
2
+ import os
1
3
  import types
2
4
  from typing import List, Any, Callable, Dict, Union
3
5
  from langchain_core.runnables import RunnableLambda, RunnableSequence
4
6
  import logging
5
7
 
8
+ import mlflow
9
+
10
+ from mlflow.models.signature import ModelSignature
11
+ from mlflow.types.schema import Schema, ColSpec
12
+ from fairo.core.agent.base_agent import SimpleAgent
13
+ from fairo.core.client.client import BaseClient
14
+ from fairo.core.execution.env_finder import read_variables
15
+ from fairo.core.runnable.runnable import Runnable
16
+ from fairo.core.workflow.utils import output_workflow_process_graph
17
+ from fairo.settings import get_fairo_api_key, get_fairo_api_secret, get_mlflow_experiment_name, get_mlflow_server, get_fairo_base_url
18
+
6
19
  # Optional interfaces/types
7
20
  class LLMAgentOutput:
8
21
  pass
9
22
 
10
- class BaseClient:
11
- pass
12
-
13
23
  logger = logging.getLogger(__name__)
14
24
 
15
- class AgentExecutor:
25
+ class FairoExecutor:
16
26
  def __init__(
17
27
  self,
18
28
  agents: List[Any],
19
29
  verbose: bool = False,
20
30
  patch_run_output_json: Callable[[LLMAgentOutput], None] = None,
21
- client: BaseClient = None,
22
- workflow_run_id: str = ""
31
+ workflow_run_id: str = "",
32
+ runnable: Runnable = None,
33
+ experiment_name: str = None
23
34
  ):
24
35
  self.agents = agents
25
36
  self.verbose = verbose
26
37
  self.patch_run_output_json = patch_run_output_json
27
- self.client = client
28
38
  self.workflow_run_id = workflow_run_id
29
-
39
+ self.runnable = runnable
40
+ self.experiment_name = experiment_name if experiment_name else get_mlflow_experiment_name()
41
+ self.setup_mlflow()
42
+ self.client = BaseClient(
43
+ base_url=get_fairo_base_url(),
44
+ password=get_fairo_api_secret(),
45
+ username=get_fairo_api_key()
46
+ )
30
47
  # Inject shared attributes into agents
31
48
  for agent in self.agents:
32
- if hasattr(agent, 'patch_run_output_json'):
33
- agent.patch_run_output_json = self.patch_run_output_json
34
49
  if hasattr(agent, 'set_client'):
35
50
  agent.set_client(self.client)
36
51
  if hasattr(agent, 'verbose'):
37
52
  agent.verbose = self.verbose
38
- if hasattr(agent, 'workflow_run_id'):
39
- agent.set_workflow_run_id(self.workflow_run_id)
40
53
 
41
54
  self.pipeline = self._build_pipeline()
42
55
 
@@ -86,12 +99,72 @@ class AgentExecutor:
86
99
  runnables.append(
87
100
  self._wrap_agent_runnable(agent, agent.input_key, agent.output_key)
88
101
  )
89
-
102
+ first_input_key = self.agents[0].input_key
103
+ last_output_key = self.agents[-1].output_key
90
104
  # Build RunnableSequence from all steps
91
105
  pipeline = runnables[0]
92
106
  for r in runnables[1:]:
93
107
  pipeline = pipeline | r # chaining
94
-
108
+
109
+ def save_process_graph():
110
+ process_graph = (
111
+ output_workflow_process_graph(self.agents)
112
+ if all(isinstance(agent, SimpleAgent) for agent in self.agents)
113
+ else None
114
+ )
115
+ if len(self.agents) > 1:
116
+ type = "Workflow"
117
+ else:
118
+ type = "Agent"
119
+ fairo_settings = {
120
+ "type": type,
121
+ "process_graph": process_graph,
122
+ }
123
+ if process_graph:
124
+ mlflow.log_text(json.dumps(fairo_settings, ensure_ascii=False, indent=2), artifact_file="fairo_settings.txt")
125
+ save_process_graph()
126
+ try:
127
+ # Find environment variables used in the project
128
+ all_env_vars = read_variables()
129
+ # Log the file as an artifact
130
+ mlflow.log_text(all_env_vars, artifact_file="environment/variables.txt")
131
+ if self.verbose:
132
+ logger.info(f"Logged {len(all_env_vars)} environment variables as artifact")
133
+ except Exception as e:
134
+ logger.warning(f"Failed to log environment variables: {str(e)}")
135
+
136
+ input_schema = Schema([
137
+ ColSpec(type="string", name=first_input_key),
138
+ ])
139
+
140
+ output_schema = Schema([
141
+ ColSpec(type="string", name=last_output_key),
142
+ ])
143
+ model_info = mlflow.langchain.log_model(
144
+ pipeline,
145
+ artifact_path="",
146
+ signature=ModelSignature(inputs=input_schema, outputs=output_schema)
147
+ )
148
+ # If runnable object was added, check if it exists, if yes, just set tags for the trace, otherwise create it
149
+ if self.runnable:
150
+ if not self.runnable.id:
151
+ result = mlflow.register_model(
152
+ model_uri=model_info.model_uri,
153
+ name=self.runnable.name,
154
+ await_registration_for=0
155
+ )
156
+ self.runnable.create_version(
157
+ artifact_path=result.source,
158
+ registered_model_id=f"models:/{self.runnable.name}/{result.version}"
159
+ )
160
+ mlflow.set_tags({
161
+ "runnable_id": self.runnable.id,
162
+ "environment": "development",
163
+ })
164
+ else:
165
+ mlflow.set_tags({
166
+ "environment": "development",
167
+ })
95
168
  return pipeline
96
169
 
97
170
  def run(self, input_data: Union[str, Dict[str, str]]) -> Dict[str, Any]:
@@ -127,4 +200,23 @@ class AgentExecutor:
127
200
  logger.error(f"Pipeline execution failed: {str(e)}")
128
201
 
129
202
  # Propagate the exception so calling code can handle it
130
- raise
203
+ raise e
204
+
205
+ def setup_mlflow(self):
206
+ def _clean_mlflow_env_vars():
207
+ for env_var in ["MLFLOW_TRACKING_USERNAME", "MLFLOW_TRACKING_PASSWORD", "MLFLOW_TRACKING_TOKEN"]:
208
+ if env_var in os.environ:
209
+ del os.environ[env_var]
210
+ def setup_mlflow_tracking_server():
211
+ os.environ["MLFLOW_TRACKING_USERNAME"] = get_fairo_api_key()
212
+ os.environ["MLFLOW_TRACKING_PASSWORD"] = get_fairo_api_secret()
213
+ mlflow.set_tracking_uri(get_mlflow_server())
214
+ mlflow.set_experiment(experiment_name=self.experiment_name)
215
+ _clean_mlflow_env_vars()
216
+ setup_mlflow_tracking_server()
217
+ with mlflow.start_run():
218
+ mlflow.langchain.autolog(
219
+ log_traces=True,
220
+ log_input_examples=True,
221
+ )
222
+
@@ -0,0 +1,77 @@
1
+ from typing import Any, List, Literal, Optional
2
+
3
+ from fairo.core.agent.base_agent import SimpleAgent
4
+ from fairo.core.client.client import BaseClient
5
+ from fairo.core.workflow.utils import output_workflow_process_graph
6
+ from fairo.settings import get_fairo_base_url, get_fairo_api_key, get_fairo_api_secret
7
+
8
+ class Runnable:
9
+ def __init__(self,
10
+ name: str,
11
+ version: int,
12
+ type: Literal["Agent", "Workflow", "Default"],
13
+ chain: List[Any] = [],
14
+ agent: Optional[SimpleAgent] = None,
15
+ artifact_path: Optional[str] = None,
16
+ description: Optional[str] = ""):
17
+ self.id = None
18
+ self.process_graph = None
19
+ self.name = name
20
+ self.version = version
21
+ self.type = type
22
+ self.chain = chain
23
+ self.agent = agent
24
+ self.artifact_path = artifact_path
25
+ self.description = description
26
+ self.client = BaseClient(
27
+ base_url=get_fairo_base_url(),
28
+ username=get_fairo_api_key(),
29
+ password=get_fairo_api_secret()
30
+ )
31
+
32
+ self.load_version()
33
+
34
+
35
+ def load_version(self):
36
+ try:
37
+ response = self.client.get(f"/runnables?version={self.version}&name={self.name}&page_size=1")
38
+ if len(response.get('results')) > 0:
39
+ runnable_obj = response.get('results')[0]
40
+ self.artifact_path = runnable_obj.get('artifact_path')
41
+ self.type = runnable_obj.get('type')
42
+ self.description = runnable_obj.get('description')
43
+ self.id = runnable_obj.get('id')
44
+ self.process_graph = runnable_obj.get('process_graph')
45
+ except Exception as e:
46
+ print("Failed to check existing runnable version")
47
+ raise e
48
+
49
+ def create_version(self, artifact_path, registered_model_id):
50
+ try:
51
+ process_graph = output_workflow_process_graph(self.chain) if all(isinstance(agent, SimpleAgent) for agent in self.chain) else None
52
+ payload = {
53
+ "name": self.name,
54
+ "version": self.version,
55
+ "artifact_path": artifact_path,
56
+ "description": self.description,
57
+ "type": self.type,
58
+ "registered_model_id": registered_model_id,
59
+ "process_graph": process_graph
60
+ }
61
+ response = self.client.post(f"/runnables", json=payload)
62
+ self.id = response.get('id')
63
+ self.process_graph = response.get('process_graph')
64
+ except Exception as e:
65
+ print("Failed to create runnable version")
66
+ raise e
67
+
68
+ def patch_process_graph(self):
69
+ try:
70
+ process_graph = output_workflow_process_graph(self.chain)
71
+ response = self.client.patch(f"/runnables/{self.id}", json={
72
+ "process_graph": process_graph
73
+ }, auth=(self.api_key, self.api_secret))
74
+ return response.json()
75
+ except Exception as e:
76
+ print(e)
77
+
@@ -8,7 +8,8 @@ from fairo.core.agent.base_agent import SimpleAgent
8
8
  from fairo.core.agent.tools.utils import FlowOutput, LLMAgentOutput
9
9
  from fairo.core.client.client import BaseClient
10
10
 
11
- from fairo.core.execution.executor import AgentExecutor
11
+ from fairo.core.execution.executor import FairoExecutor
12
+ from fairo.core.runnable.runnable import Runnable
12
13
  from fairo.core.workflow.utils import output_workflow_process_graph
13
14
  from fairo.settings import (
14
15
  get_fairo_api_key,
@@ -219,7 +220,7 @@ class BaseWorkflow:
219
220
  Propagates any exceptions from agents.
220
221
  """
221
222
  client = BaseClient(base_url=self.base_url, username=self.api_key, password=self.api_secret)
222
- executor = AgentExecutor(
223
+ executor = FairoExecutor(
223
224
  agents=self.agents,
224
225
  verbose=False,
225
226
  patch_run_output_json=self.add_workflow_run_node_output,
File without changes
@@ -54,6 +54,8 @@ def get_mlflow_token():
54
54
  def get_mlflow_experiment_path():
55
55
  return os.getenv('MLFLOW_EXPERIMENT_PATH', None)
56
56
 
57
+ def get_mlflow_experiment_name():
58
+ return os.getenv('MLFLOW_EXPERIMENT_NAME', "Development Default")
57
59
 
58
60
  def get_use_databricks_tracking_server():
59
61
  return os.getenv('USE_DATABRICKS_TRACKING_SERVER', False)
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fairo
3
- Version: 25.5.4
3
+ Version: 25.6.2
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
@@ -20,13 +20,18 @@ fairo/core/agent/tools/__init__.py
20
20
  fairo/core/agent/tools/base_tools.py
21
21
  fairo/core/agent/tools/code_analysis.py
22
22
  fairo/core/agent/tools/utils.py
23
+ fairo/core/chat/__init__.py
24
+ fairo/core/chat/chat.py
23
25
  fairo/core/client/__init__.py
24
26
  fairo/core/client/client.py
25
27
  fairo/core/execution/__init__.py
28
+ fairo/core/execution/env_finder.py
26
29
  fairo/core/execution/executor.py
27
30
  fairo/core/models/__init__.py
28
31
  fairo/core/models/custom_field_value.py
29
32
  fairo/core/models/resources.py
33
+ fairo/core/runnable/__init__.py
34
+ fairo/core/runnable/runnable.py
30
35
  fairo/core/workflow/__init__.py
31
36
  fairo/core/workflow/base_workflow.py
32
37
  fairo/core/workflow/dependency.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes