flo-ai 0.0.5.dev1__tar.gz → 0.0.5.dev3__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.
Files changed (59) hide show
  1. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/PKG-INFO +6 -2
  2. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/README.md +5 -1
  3. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/core.py +3 -1
  4. flo_ai-0.0.5.dev3/flo_ai/parsers/flo_json_parser.py +112 -0
  5. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/pyproject.toml +1 -1
  6. flo_ai-0.0.5.dev1/flo_ai/parsers/flo_json_parser.py +0 -61
  7. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/LICENSE +0 -0
  8. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/__init__.py +0 -0
  9. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/builders/__init__.py +0 -0
  10. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/builders/yaml_builder.py +0 -0
  11. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/callbacks/__init__.py +0 -0
  12. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/callbacks/flo_callbacks.py +0 -0
  13. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/callbacks/flo_execution_logger.py +0 -0
  14. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/common/README.md +0 -0
  15. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/common/__init__.py +0 -0
  16. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/common/flo_langchain_logger.py +0 -0
  17. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/common/flo_logger.py +0 -0
  18. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/constants/__init__.py +0 -0
  19. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/constants/common_constants.py +0 -0
  20. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/constants/flo_node_contants.py +0 -0
  21. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/constants/prompt_constants.py +0 -0
  22. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/error/flo_exception.py +0 -0
  23. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/factory/agent_factory.py +0 -0
  24. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/helpers/utils.py +0 -0
  25. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/__init__.py +0 -0
  26. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/delegate.py +0 -0
  27. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/exception.py +0 -0
  28. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_agent.py +0 -0
  29. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_delegation_agent.py +0 -0
  30. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_executable.py +0 -0
  31. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_llm_agent.py +0 -0
  32. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_member.py +0 -0
  33. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_node.py +0 -0
  34. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_reflection_agent.py +0 -0
  35. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_routed_team.py +0 -0
  36. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_team.py +0 -0
  37. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/models/flo_tool_agent.py +0 -0
  38. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/parsers/flo_parser.py +0 -0
  39. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/parsers/flo_pydantic_parser.py +0 -0
  40. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/retrievers/__init__.py +0 -0
  41. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/retrievers/flo_compression_pipeline.py +0 -0
  42. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/retrievers/flo_multi_query.py +0 -0
  43. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/retrievers/flo_retriever.py +0 -0
  44. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/router/__init__.py +0 -0
  45. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/router/flo_linear.py +0 -0
  46. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/router/flo_llm_router.py +0 -0
  47. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/router/flo_router.py +0 -0
  48. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/router/flo_router_factory.py +0 -0
  49. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/router/flo_supervisor.py +0 -0
  50. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/state/__init__.py +0 -0
  51. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/state/flo_data_collector.py +0 -0
  52. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/state/flo_kv_collector.py +0 -0
  53. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/state/flo_session.py +0 -0
  54. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/state/flo_state.py +0 -0
  55. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/storage/data_collector.py +0 -0
  56. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/tools/__init__.py +0 -0
  57. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/tools/flo_tool.py +0 -0
  58. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/yaml/config.py +0 -0
  59. {flo_ai-0.0.5.dev1 → flo_ai-0.0.5.dev3}/flo_ai/yaml/validators.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flo-ai
3
- Version: 0.0.5.dev1
3
+ Version: 0.0.5.dev3
4
4
  Summary: A easy way to create structured AI agents
5
5
  License: MIT
6
6
  Author: vizsatiz
@@ -369,7 +369,11 @@ Built with ❤️ using:
369
369
  <p><b>Build an Agentic RAG using FloAI in minutes</b><br />FloAI has just made implementing agentic RAG simple and easy to manage</p>
370
370
  </a>
371
371
  </div>
372
-
372
+ <a href="https://medium.com/rootflo/mastering-ai-interaction-logging-and-data-collection-with-floai-a490818bb2f1" target="_blank" style="text-decoration: none;">
373
+ <img src="./images/blog-image.png" width="150" style="border-radius: 10px;" />
374
+ <p><b>Mastering AI Interaction Logging and Data Collection with FloAI</b><br />Learn how to leverage FloAI's powerful logging system for debugging, training data generation, and system optimization</p>
375
+ </a>
376
+ </a>
373
377
  ---
374
378
 
375
379
  <div align="center">
@@ -347,7 +347,11 @@ Built with ❤️ using:
347
347
  <p><b>Build an Agentic RAG using FloAI in minutes</b><br />FloAI has just made implementing agentic RAG simple and easy to manage</p>
348
348
  </a>
349
349
  </div>
350
-
350
+ <a href="https://medium.com/rootflo/mastering-ai-interaction-logging-and-data-collection-with-floai-a490818bb2f1" target="_blank" style="text-decoration: none;">
351
+ <img src="./images/blog-image.png" width="150" style="border-radius: 10px;" />
352
+ <p><b>Mastering AI Interaction Logging and Data Collection with FloAI</b><br />Learn how to leverage FloAI's powerful logging system for debugging, training data generation, and system optimization</p>
353
+ </a>
354
+ </a>
351
355
  ---
352
356
 
353
357
  <div align="center">
@@ -8,6 +8,7 @@ from flo_ai.builders.yaml_builder import build_supervised_team
8
8
  from typing import Any, Iterator, Union
9
9
  from flo_ai.router.flo_router import FloRouter
10
10
  from flo_ai.state.flo_session import FloSession
11
+ from flo_ai.models.flo_llm_agent import FloLLMAgent
11
12
  from flo_ai.models.flo_executable import ExecutableFlo
12
13
  from flo_ai.error.flo_exception import FloException
13
14
  from flo_ai.constants.common_constants import DOCUMENTATION_WEBSITE
@@ -95,7 +96,8 @@ class Flo:
95
96
  executable: ExecutableFlo = build_supervised_team(
96
97
  session, to_supervised_team(yaml)
97
98
  )
98
- if isinstance(executable, FloAgent):
99
+ # TODO fix this for all agents later
100
+ if isinstance(executable, FloAgent) or isinstance(executable, FloLLMAgent):
99
101
  executable = FloNode.Builder(session).build_from_agent(executable)
100
102
  return Flo(session, executable)
101
103
  if routed_team is not None:
@@ -0,0 +1,112 @@
1
+ import json
2
+ import csv
3
+ from io import StringIO
4
+ from flo_ai.parsers.flo_parser import FloParser
5
+ from typing import List, Dict, Any, Optional, Literal
6
+ from pydantic import BaseModel, Field, create_model
7
+ from flo_ai.error.flo_exception import FloException
8
+ from langchain_core.output_parsers import PydanticOutputParser
9
+ from dataclasses import dataclass
10
+
11
+
12
+ @dataclass
13
+ class ParseContract:
14
+ name: str
15
+ fields: List[Dict[str, Any]]
16
+
17
+
18
+ class FloJsonParser(FloParser):
19
+ def __init__(self, parse_contract: ParseContract):
20
+ self.contract = parse_contract
21
+ super().__init__()
22
+
23
+ def __dict_list_to_csv_string(self, data):
24
+ if not data or len(data) == 0:
25
+ return '```No data provided```'
26
+ headers = data[0].keys()
27
+ output = StringIO()
28
+
29
+ writer = csv.DictWriter(output, fieldnames=headers)
30
+ writer.writeheader()
31
+ writer.writerows(data)
32
+
33
+ csv_string = output.getvalue()
34
+ output.close()
35
+
36
+ return f'```\n{csv_string}```'
37
+
38
+ def __create_contract_from_json(self) -> BaseModel:
39
+ type_mapping = {
40
+ 'str': str,
41
+ 'int': int,
42
+ 'bool': bool,
43
+ 'float': float,
44
+ 'literal': Literal,
45
+ }
46
+ pydantic_fields = {}
47
+ for field in self.contract.fields:
48
+ field_type = field['type']
49
+ if field_type == 'literal':
50
+ literal_values = field.get('values', [])
51
+ if not literal_values:
52
+ raise ValueError(
53
+ f"Field '{field['name']}' of type 'literal' must specify 'values'."
54
+ )
55
+ literals = [literal_value['value'] for literal_value in literal_values]
56
+ field_type_annotation = Literal[tuple(literals)]
57
+ default_prompt = (
58
+ field['default_value_prompt']
59
+ if 'default_value_prompt' in field
60
+ else ''
61
+ )
62
+ field_description = f"""
63
+ {field['description']}
64
+ Following are the list of possibles values and its correponding description:
65
+ {self.__dict_list_to_csv_string(literal_values)}
66
+
67
+ This should be one of the values in the `value` column in the above csv.
68
+ {default_prompt}
69
+ """
70
+ else:
71
+ field_type_annotation = type_mapping.get(field_type)
72
+ if field_type_annotation is None:
73
+ raise ValueError(f'Unsupported type: {field_type}')
74
+ field_description = field['description']
75
+
76
+ pydantic_fields[field['name']] = (
77
+ field_type_annotation,
78
+ Field(..., description=field_description),
79
+ )
80
+
81
+ DynamicModel = create_model(self.contract.name, **pydantic_fields)
82
+ return DynamicModel
83
+
84
+ def get_format_instructions(self):
85
+ return PydanticOutputParser(
86
+ pydantic_object=self.__create_contract_from_json()
87
+ ).get_format_instructions()
88
+
89
+ def create(json_dict: Optional[Dict] = None, json_path: Optional[str] = None):
90
+ return FloJsonParser.Builder(json_dict=json_dict, json_path=json_path).build()
91
+
92
+ class Builder:
93
+ def __init__(
94
+ self, json_dict: Optional[Dict] = None, json_path: Optional[str] = None
95
+ ):
96
+ if json_dict is None and json_path is None:
97
+ raise FloException(
98
+ 'Either of json_dict or json_path is required to build a FloJsonParser'
99
+ )
100
+ self.json_dict = json_dict
101
+ self.json_path = json_path
102
+
103
+ def build(self):
104
+ if self.json_dict:
105
+ name = self.json_dict['name']
106
+ fields = self.json_dict['fields']
107
+ else:
108
+ with open(self.json_path) as f:
109
+ json_contract = json.load(f)
110
+ name = json_contract['name']
111
+ fields = json_contract['fields']
112
+ return FloJsonParser(ParseContract(name=name, fields=fields))
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "flo-ai"
3
- version = "0.0.5-dev1"
3
+ version = "0.0.5-dev3"
4
4
  description = "A easy way to create structured AI agents"
5
5
  authors = ["vizsatiz <vishnu@rootfor.xyz>"]
6
6
  license = "MIT"
@@ -1,61 +0,0 @@
1
- import json
2
- from flo_ai.parsers.flo_parser import FloParser
3
- from typing import List, Dict, Any, Optional
4
- from pydantic import BaseModel, Field, create_model
5
- from flo_ai.error.flo_exception import FloException
6
- from langchain_core.output_parsers import PydanticOutputParser
7
- from dataclasses import dataclass
8
-
9
-
10
- @dataclass
11
- class ParseContract:
12
- name: str
13
- fields: List[Dict[str, Any]]
14
-
15
-
16
- class FloJsonParser(FloParser):
17
- def __init__(self, parse_contract: ParseContract):
18
- self.contract = parse_contract
19
- super().__init__()
20
-
21
- def __create_contract_from_json(self) -> BaseModel:
22
- type_mapping = {'str': str, 'int': int, 'bool': bool, 'float': float}
23
- pydantic_fields = {
24
- field['name']: (
25
- type_mapping[field['type']],
26
- Field(..., description=field['description']),
27
- )
28
- for field in self.contract.fields
29
- }
30
- DynamicModel = create_model(self.contract.name, **pydantic_fields)
31
- return DynamicModel
32
-
33
- def get_format_instructions(self):
34
- return PydanticOutputParser(
35
- pydantic_object=self.__create_contract_from_json()
36
- ).get_format_instructions()
37
-
38
- def create(json_dict: Optional[Dict] = None, json_path: Optional[str] = None):
39
- return FloJsonParser.Builder(json_dict=json_dict, json_path=json_path).build()
40
-
41
- class Builder:
42
- def __init__(
43
- self, json_dict: Optional[Dict] = None, json_path: Optional[str] = None
44
- ):
45
- if json_dict is None and json_path is None:
46
- raise FloException(
47
- 'Either of json_dict or json_path is required to build a FloJsonParser'
48
- )
49
- self.json_dict = json_dict
50
- self.json_path = json_path
51
-
52
- def build(self):
53
- if self.json_dict:
54
- name = self.json_dict['name']
55
- fields = self.json_dict['fields']
56
- else:
57
- with open(self.json_path) as f:
58
- json_contract = json.load(f)
59
- name = json_contract['name']
60
- fields = json_contract['fields']
61
- return FloJsonParser(ParseContract(name=name, fields=fields))
File without changes