lionagi 0.12.2__py3-none-any.whl → 0.12.3__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.
lionagi/fields/file.py CHANGED
@@ -71,7 +71,7 @@ class File(HashableModel):
71
71
  header: str | None = None,
72
72
  footer: str | None = None,
73
73
  ) -> Path:
74
- from lionagi.libs.file.create_path import create_path
74
+ from lionagi.utils import create_path
75
75
 
76
76
  fp = create_path(
77
77
  directory=directory,
lionagi/fields/reason.py CHANGED
@@ -4,8 +4,8 @@
4
4
 
5
5
  from pydantic import Field, field_validator
6
6
 
7
- from lionagi.libs.parse.to_num import to_num
8
7
  from lionagi.models import FieldModel, HashableModel
8
+ from lionagi.utils import to_num
9
9
 
10
10
  __all__ = ("Reason",)
11
11
 
@@ -1,12 +1,7 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
1
  from pathlib import Path
6
2
  from typing import Any
7
3
 
8
- from lionagi.libs.file.create_path import create_path
9
- from lionagi.utils import lcall
4
+ from lionagi.utils import create_path, lcall
10
5
 
11
6
  from .process import dir_to_files
12
7
 
@@ -1,10 +1,6 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
1
  from pathlib import Path
6
2
 
7
- from lionagi.libs.file.create_path import create_path
3
+ from lionagi.utils import create_path
8
4
 
9
5
  from .process import dir_to_files
10
6
 
lionagi/libs/file/save.py CHANGED
@@ -7,7 +7,7 @@ import logging
7
7
  from pathlib import Path
8
8
  from typing import Any
9
9
 
10
- from .create_path import create_path
10
+ from lionagi.utils import create_path
11
11
 
12
12
 
13
13
  def save_to_file(
@@ -2,184 +2,15 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- import logging
6
- import shutil
7
- import subprocess
8
- import sys
9
- from collections.abc import Sequence
10
- from typing import Any
11
-
12
- from lionagi.utils import is_import_installed
13
-
14
-
15
- def run_package_manager_command(
16
- args: Sequence[str],
17
- ) -> subprocess.CompletedProcess[bytes]:
18
- """Run a package manager command, using uv if available, otherwise falling back to pip."""
19
- # Check if uv is available in PATH
20
- uv_path = shutil.which("uv")
21
-
22
- if uv_path:
23
- # Use uv if available
24
- try:
25
- return subprocess.run(
26
- [uv_path] + list(args),
27
- check=True,
28
- capture_output=True,
29
- )
30
- except subprocess.CalledProcessError:
31
- # If uv fails, fall back to pip
32
- print("uv command failed, falling back to pip...")
33
-
34
- # Fall back to pip
35
- return subprocess.run(
36
- [sys.executable, "-m", "pip"] + list(args),
37
- check=True,
38
- capture_output=True,
39
- )
40
-
41
-
42
- def check_import(
43
- package_name: str,
44
- module_name: str | None = None,
45
- import_name: str | None = None,
46
- pip_name: str | None = None,
47
- attempt_install: bool = True,
48
- error_message: str = "",
49
- ):
50
- """
51
- Check if a package is installed, attempt to install if not.
52
-
53
- Args:
54
- package_name: The name of the package to check.
55
- module_name: The specific module to import (if any).
56
- import_name: The specific name to import from the module (if any).
57
- pip_name: The name to use for pip installation (if different).
58
- attempt_install: Whether to attempt installation if not found.
59
- error_message: Custom error message to use if package not found.
60
-
61
- Raises:
62
- ImportError: If the package is not found and not installed.
63
- ValueError: If the import fails after installation attempt.
64
- """
65
- if not is_import_installed(package_name):
66
- if attempt_install:
67
- logging.info(
68
- f"Package {package_name} not found. Attempting " "to install.",
69
- )
70
- try:
71
- return install_import(
72
- package_name=package_name,
73
- module_name=module_name,
74
- import_name=import_name,
75
- pip_name=pip_name,
76
- )
77
- except ImportError as e:
78
- raise ValueError(
79
- f"Failed to install {package_name}: {e}"
80
- ) from e
81
- else:
82
- logging.info(
83
- f"Package {package_name} not found. {error_message}",
84
- )
85
- raise ImportError(
86
- f"Package {package_name} not found. {error_message}",
87
- )
88
-
89
- return import_module(
90
- package_name=package_name,
91
- module_name=module_name,
92
- import_name=import_name,
93
- )
94
-
95
-
96
- def import_module(
97
- package_name: str,
98
- module_name: str = None,
99
- import_name: str | list = None,
100
- ) -> Any:
101
- """
102
- Import a module by its path.
103
-
104
- Args:
105
- module_path: The path of the module to import.
106
-
107
- Returns:
108
- The imported module.
109
-
110
- Raises:
111
- ImportError: If the module cannot be imported.
112
- """
113
- try:
114
- full_import_path = (
115
- f"{package_name}.{module_name}" if module_name else package_name
116
- )
117
-
118
- if import_name:
119
- import_name = (
120
- [import_name]
121
- if not isinstance(import_name, list)
122
- else import_name
123
- )
124
- a = __import__(
125
- full_import_path,
126
- fromlist=import_name,
127
- )
128
- if len(import_name) == 1:
129
- return getattr(a, import_name[0])
130
- return [getattr(a, name) for name in import_name]
131
- else:
132
- return __import__(full_import_path)
133
-
134
- except ImportError as e:
135
- raise ImportError(
136
- f"Failed to import module {full_import_path}: {e}"
137
- ) from e
138
-
139
-
140
- def install_import(
141
- package_name: str,
142
- module_name: str | None = None,
143
- import_name: str | None = None,
144
- pip_name: str | None = None,
145
- ):
146
- """
147
- Attempt to import a package, installing it if not found.
148
-
149
- Args:
150
- package_name: The name of the package to import.
151
- module_name: The specific module to import (if any).
152
- import_name: The specific name to import from the module (if any).
153
- pip_name: The name to use for pip installation (if different).
154
-
155
- Raises:
156
- ImportError: If the package cannot be imported or installed.
157
- subprocess.CalledProcessError: If pip installation fails.
158
- """
159
- pip_name = pip_name or package_name
160
-
161
- try:
162
- return import_module(
163
- package_name=package_name,
164
- module_name=module_name,
165
- import_name=import_name,
166
- )
167
- except ImportError:
168
- logging.info(f"Installing {pip_name}...")
169
- try:
170
- run_package_manager_command(["install", pip_name])
171
- return import_module(
172
- package_name=package_name,
173
- module_name=module_name,
174
- import_name=import_name,
175
- )
176
- except subprocess.CalledProcessError as e:
177
- raise ImportError(f"Failed to install {pip_name}: {e}") from e
178
- except ImportError as e:
179
- raise ImportError(
180
- f"Failed to import {pip_name} after installation: {e}"
181
- ) from e
5
+ from lionagi.utils import (
6
+ check_import,
7
+ import_module,
8
+ install_import,
9
+ is_import_installed,
10
+ run_package_manager_command,
11
+ )
182
12
 
13
+ # backward compatibility
183
14
 
184
15
  __all__ = (
185
16
  "run_package_manager_command",
lionagi/libs/parse.py ADDED
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from lionagi.libs.schema.as_readable import as_readable
6
+ from lionagi.libs.schema.extract_code_block import extract_code_block
7
+ from lionagi.libs.schema.function_to_schema import function_to_schema
8
+ from lionagi.libs.validate.fuzzy_match_keys import fuzzy_match_keys
9
+ from lionagi.libs.validate.fuzzy_validate_mapping import fuzzy_validate_mapping
10
+ from lionagi.libs.validate.string_similarity import string_similarity
11
+ from lionagi.utils import fuzzy_parse_json, to_dict, to_json, to_num
12
+
13
+ validate_keys = fuzzy_match_keys # for backward compatibility
14
+ validate_mapping = fuzzy_validate_mapping # for backward compatibility
15
+
16
+
17
+ __all__ = (
18
+ "as_readable",
19
+ "extract_code_block",
20
+ "function_to_schema",
21
+ "fuzzy_match_keys",
22
+ "fuzzy_validate_mapping",
23
+ "string_similarity",
24
+ "validate_keys",
25
+ "validate_mapping",
26
+ "to_dict",
27
+ "to_json",
28
+ "to_num",
29
+ "fuzzy_parse_json",
30
+ )
@@ -1,52 +1,52 @@
1
1
  {
2
- "options": {
3
- "math": {
4
- "name": "Mathematical Framework",
5
- "description": "Offers a suite of math glyphs and notation rules.",
6
- "glyphs": [
7
- {
8
- "symbol": "\u21b9",
9
- "name": "Focus/Filter",
10
- "description": "Used for focusing instructions"
2
+ "options": {
3
+ "math": {
4
+ "name": "Mathematical Framework",
5
+ "description": "Offers a suite of math glyphs and notation rules.",
6
+ "glyphs": [
7
+ {
8
+ "symbol": "\u21b9",
9
+ "name": "Focus/Filter",
10
+ "description": "Used for focusing instructions"
11
+ },
12
+ {
13
+ "symbol": "\u03a3",
14
+ "name": "Summarize",
15
+ "description": "Condense large sets of data"
16
+ },
17
+ {
18
+ "symbol": "\u2295",
19
+ "name": "Combine/Merge",
20
+ "description": "Merge multiple data sources"
21
+ },
22
+ {
23
+ "symbol": "\u2022",
24
+ "name": "Group Operation",
25
+ "description": "Binary operation in group theory"
26
+ }
27
+ ]
11
28
  },
12
- {
13
- "symbol": "\u03a3",
14
- "name": "Summarize",
15
- "description": "Condense large sets of data"
29
+ "optim": {
30
+ "name": "Optimization Framework",
31
+ "description": "Compression and optimization for code/math expressions.",
32
+ "glyphs": [
33
+ {
34
+ "symbol": "IF",
35
+ "name": "Conditional Operator",
36
+ "description": "Represents branching logic"
37
+ }
38
+ ]
16
39
  },
17
- {
18
- "symbol": "\u2295",
19
- "name": "Combine/Merge",
20
- "description": "Merge multiple data sources"
21
- },
22
- {
23
- "symbol": "\u2022",
24
- "name": "Group Operation",
25
- "description": "Binary operation in group theory"
26
- }
27
- ]
28
- },
29
- "optim": {
30
- "name": "Optimization Framework",
31
- "description": "Compression and optimization for code/math expressions.",
32
- "glyphs": [
33
- {
34
- "symbol": "IF",
35
- "name": "Conditional Operator",
36
- "description": "Represents branching logic"
37
- }
38
- ]
39
- },
40
- "custom_algebra": {
41
- "name": "Custom Algebraic Framework",
42
- "description": "Extra rules for ring, group, field expansions.",
43
- "glyphs": [
44
- {
45
- "symbol": "\u221e",
46
- "name": "Infinite Operator",
47
- "description": "Represents unbounded algebraic ops"
40
+ "custom_algebra": {
41
+ "name": "Custom Algebraic Framework",
42
+ "description": "Extra rules for ring, group, field expansions.",
43
+ "glyphs": [
44
+ {
45
+ "symbol": "\u221e",
46
+ "name": "Infinite Operator",
47
+ "description": "Represents unbounded algebraic ops"
48
+ }
49
+ ]
48
50
  }
49
- ]
50
51
  }
51
- }
52
52
  }
@@ -11,8 +11,7 @@ from typing import Any
11
11
 
12
12
  from pydantic import BaseModel, Field, PrivateAttr, field_validator
13
13
 
14
- from lionagi.libs.file.create_path import create_path
15
- from lionagi.utils import to_dict
14
+ from lionagi.utils import create_path, to_dict
16
15
 
17
16
  from .._concepts import Manager
18
17
  from .element import Element
@@ -19,14 +19,10 @@ message_text = template.render(**args)
19
19
  print(message_text)
20
20
  ```
21
21
 
22
- Benefits and Customization • You can easily rearrange sections within these
23
- templates without changing your code logic. • Each message type is clearly
24
- separated, making it simpler to maintain or adjust one message format without
25
- affecting the others. • If you find that you use some snippet (like rendering a
26
- schema) in multiple templates, you can factor it out into its own partial
27
- template (like tool_schemas.jinja2) and include it where needed. • Over time,
28
- you can add more templates or split existing ones if certain messages become too
29
- complex.
22
+ Benefits and Customization
23
+ • You can easily rearrange sections within these templates without changing your code logic.
24
+ • Each message type is clearly separated, making it simpler to maintain or adjust one message format without affecting the others.
25
+ • If you find that you use some snippet (like rendering a schema) in multiple templates, you can factor it out into its own partial template (like tool_schemas.jinja2) and include it where needed.
26
+ • Over time, you can add more templates or split existing ones if certain messages become too complex.
30
27
 
31
- By establishing this set of base templates and arguments, you have a starting
32
- point. You can expand or refine as your requirements evolve.
28
+ By establishing this set of base templates and arguments, you have a starting point. You can expand or refine as your requirements evolve.
@@ -1,3 +1,160 @@
1
- from khive.providers.exa_ import ExaSearchRequest
1
+ from enum import Enum
2
2
 
3
- __all__ = ("ExaSearchRequest",)
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class CategoryEnum(str, Enum):
7
+ company = "company"
8
+ research_paper = "research paper"
9
+ news = "news"
10
+ pdf = "pdf"
11
+ github = "github"
12
+ tweet = "tweet"
13
+ personal_site = "personal site"
14
+ linkedin_profile = "linkedin profile"
15
+ financial_report = "financial report"
16
+
17
+
18
+ class LivecrawlEnum(str, Enum):
19
+ never = "never"
20
+ fallback = "fallback"
21
+ always = "always"
22
+
23
+
24
+ class SearchTypeEnum(str, Enum):
25
+ keyword = "keyword"
26
+ neural = "neural"
27
+ auto = "auto"
28
+
29
+
30
+ class ContentsText(BaseModel):
31
+ includeHtmlTags: bool | None = Field(
32
+ default=False,
33
+ description="Whether to include HTML tags in the text. Set to True if you want to retain HTML structure for the LLM to interpret.",
34
+ )
35
+ maxCharacters: int | None = Field(
36
+ default=None,
37
+ description="The maximum number of characters to return from the webpage text.",
38
+ )
39
+
40
+
41
+ class ContentsHighlights(BaseModel):
42
+ highlightsPerUrl: int | None = Field(
43
+ default=1,
44
+ description="The number of highlight snippets you want per page.",
45
+ )
46
+ numSentences: int | None = Field(
47
+ default=5,
48
+ description="Number of sentences to return in each highlight snippet.",
49
+ )
50
+ query: None | str = Field(
51
+ default=None,
52
+ description="A specific query used to generate the highlight snippets.",
53
+ )
54
+
55
+
56
+ class ContentsSummary(BaseModel):
57
+ query: None | str = Field(
58
+ default=None,
59
+ description="A specific query used to generate a summary of the webpage.",
60
+ )
61
+
62
+
63
+ class ContentsExtras(BaseModel):
64
+ links: int | None = Field(
65
+ default=None, description="Number of links to return from each page."
66
+ )
67
+ imageLinks: int | None = Field(
68
+ default=None, description="Number of images to return for each result."
69
+ )
70
+
71
+
72
+ class Contents(BaseModel):
73
+ text: None | ContentsText = Field(
74
+ default=None,
75
+ description="Return full or partial text for each page, with optional HTML structure or size limit.",
76
+ )
77
+ highlights: None | ContentsHighlights = Field(
78
+ default=None, description="Return snippet highlights for each page."
79
+ )
80
+ summary: None | ContentsSummary = Field(
81
+ default=None, description="Return a short summary of each page."
82
+ )
83
+ livecrawl: None | LivecrawlEnum = Field(
84
+ default=LivecrawlEnum.never,
85
+ description="Livecrawling setting for each page. Options: never, fallback, always.",
86
+ )
87
+ livecrawlTimeout: int | None = Field(
88
+ default=10000,
89
+ description="Timeout in milliseconds for livecrawling. Default 10000.",
90
+ )
91
+ subpages: int | None = Field(
92
+ default=None,
93
+ description="Number of subpages to crawl within each URL.",
94
+ )
95
+ subpageTarget: None | str | list[str] = Field(
96
+ default=None,
97
+ description="A target subpage or multiple subpages (list) to crawl, e.g. 'cited papers'.",
98
+ )
99
+ extras: None | ContentsExtras = Field(
100
+ default=None,
101
+ description="Additional extras like links or images to return for each page.",
102
+ )
103
+
104
+
105
+ class ExaSearchRequest(BaseModel):
106
+ query: str = Field(
107
+ ...,
108
+ description="The main query string describing what you're looking for.",
109
+ )
110
+ category: None | CategoryEnum = Field(
111
+ default=None,
112
+ description="A data category to focus on, such as 'company', 'research paper', 'news', etc.",
113
+ )
114
+ type: None | SearchTypeEnum = Field(
115
+ default=None,
116
+ description="The type of search to run. Can be 'auto', 'keyword', or 'neural'.",
117
+ )
118
+ useAutoprompt: None | bool = Field(
119
+ default=False,
120
+ description="If True, Exa auto-optimizes your query for best results (neural or auto search only).",
121
+ )
122
+ numResults: int | None = Field(
123
+ default=10, description="Number of results to return. Default is 10."
124
+ )
125
+ includeDomains: None | list[str] = Field(
126
+ default=None,
127
+ description="List of domains you want to include exclusively.",
128
+ )
129
+ excludeDomains: None | list[str] = Field(
130
+ default=None,
131
+ description="List of domains you do NOT want to see in the results.",
132
+ )
133
+ startCrawlDate: None | str = Field(
134
+ default=None,
135
+ description="Include results crawled after this ISO date (e.g., '2023-01-01T00:00:00.000Z').",
136
+ )
137
+ endCrawlDate: None | str = Field(
138
+ default=None,
139
+ description="Include results crawled before this ISO date.",
140
+ )
141
+ startPublishedDate: None | str = Field(
142
+ default=None,
143
+ description="Only return results published after this ISO date.",
144
+ )
145
+ endPublishedDate: None | str = Field(
146
+ default=None,
147
+ description="Only return results published before this ISO date.",
148
+ )
149
+ includeText: None | list[str] = Field(
150
+ default=None,
151
+ description="Strings that must appear in the webpage text. Only a single string up to 5 words is currently supported.",
152
+ )
153
+ excludeText: None | list[str] = Field(
154
+ default=None,
155
+ description="Strings that must NOT appear in the webpage text. Only a single string up to 5 words is currently supported.",
156
+ )
157
+ contents: None | Contents = Field(
158
+ default=None,
159
+ description="Dict defining the different ways you want to retrieve webpage contents, including text, highlights, or summaries.",
160
+ )