gofannon 0.25.20__py3-none-any.whl → 0.25.22__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.
gofannon/base/__init__.py CHANGED
@@ -8,6 +8,7 @@ from pathlib import Path
8
8
 
9
9
  import anyio
10
10
 
11
+ from .adk_mixin import AdkMixin
11
12
  from ..config import ToolConfig
12
13
 
13
14
  from .smol_agents import SmolAgentsMixin
@@ -74,6 +75,7 @@ class BaseTool(SmolAgentsMixin,
74
75
  LangflowMixin,
75
76
  MCPMixin,
76
77
  LlamaStackMixin,
78
+ AdkMixin,
77
79
  ABC):
78
80
  def __init__(self, **kwargs):
79
81
  self.logger = logging.getLogger(
@@ -0,0 +1,294 @@
1
+ # gofannon/base/adk_mixin.py
2
+
3
+ import inspect
4
+ import json
5
+ from typing import Any, Callable, Dict, List, Optional, Type as TypingType
6
+ import functools # Add this import
7
+
8
+ # Try to import ADK components
9
+ try:
10
+ from google.adk.tools import BaseTool as AdkBaseTool
11
+ from google.adk.tools import FunctionTool as AdkFunctionTool
12
+ from google.adk.tools.tool_context import ToolContext as AdkToolContext
13
+ # _automatic_function_calling_util is not typically a public export,
14
+ # but FunctionTool uses it. For export, we might need a different strategy
15
+ # or rely on AdkFunctionTool to build its declaration.
16
+ # from google.adk.tools._automatic_function_calling_util import (
17
+ # build_function_declaration as adk_build_function_declaration,
18
+ # )
19
+ from google.genai import types as adk_gemini_types
20
+ import anyio # For running sync Gofannon fn in async ADK tool
21
+
22
+ _HAS_ADK = True
23
+ except ImportError:
24
+ _HAS_ADK = False
25
+ # Define dummy types for type hinting if ADK is not present
26
+ class AdkBaseTool: pass
27
+ class AdkFunctionTool(AdkBaseTool): pass # type: ignore
28
+ class AdkToolContext: pass # type: ignore
29
+ class adk_gemini_types: # type: ignore
30
+ class Type:
31
+ STRING = "STRING"
32
+ INTEGER = "INTEGER"
33
+ NUMBER = "NUMBER"
34
+ BOOLEAN = "BOOLEAN"
35
+ ARRAY = "ARRAY"
36
+ OBJECT = "OBJECT"
37
+ TYPE_UNSPECIFIED = "TYPE_UNSPECIFIED"
38
+ class Schema: # type: ignore
39
+ def __init__(self, **kwargs):
40
+ self.type = kwargs.get('type', adk_gemini_types.Type.OBJECT)
41
+ self.description = kwargs.get('description')
42
+ self.properties = kwargs.get('properties', {})
43
+ self.items = kwargs.get('items')
44
+ self.required = kwargs.get('required', [])
45
+ self.enum = kwargs.get('enum')
46
+ self.nullable = kwargs.get('nullable')
47
+
48
+ class FunctionDeclaration: # type: ignore
49
+ def __init__(self, name, description, parameters):
50
+ self.name = name
51
+ self.description = description
52
+ self.parameters = parameters
53
+
54
+
55
+ # Helper for ADK Schema to Gofannon JSON Schema
56
+ ADK_GEMINI_TYPE_TO_JSON_TYPE = {
57
+ adk_gemini_types.Type.STRING: "string",
58
+ adk_gemini_types.Type.INTEGER: "integer",
59
+ adk_gemini_types.Type.NUMBER: "number",
60
+ adk_gemini_types.Type.BOOLEAN: "boolean",
61
+ adk_gemini_types.Type.ARRAY: "array",
62
+ adk_gemini_types.Type.OBJECT: "object",
63
+ adk_gemini_types.Type.TYPE_UNSPECIFIED: "object", # Default for unspecified
64
+ }
65
+
66
+ def _adk_schema_to_gofannon_json_schema(adk_schema: Optional[adk_gemini_types.Schema]) -> Dict[str, Any]:
67
+ if not adk_schema:
68
+ return {"type": "object", "properties": {}}
69
+
70
+ json_schema: Dict[str, Any] = {}
71
+
72
+ adk_type_enum = getattr(adk_schema, 'type', adk_gemini_types.Type.TYPE_UNSPECIFIED)
73
+ json_type_str = ADK_GEMINI_TYPE_TO_JSON_TYPE.get(adk_type_enum, "object")
74
+
75
+ if getattr(adk_schema, 'nullable', False):
76
+ # Represent nullable as a list of types including "null" if original type is singular
77
+ # or handle it based on how Gofannon expects nullable
78
+ json_schema["type"] = [json_type_str, "null"] if json_type_str != "object" else json_type_str # Pydantic v1 style for Optional[T]
79
+ if json_type_str == "object": # For objects, nullable flag is more common in JSON schema
80
+ json_schema["nullable"] = True
81
+ json_schema["type"] = "object" # Keep type as object if it was object
82
+ else:
83
+ json_schema["type"] = json_type_str
84
+
85
+ description = getattr(adk_schema, 'description', None)
86
+ if description:
87
+ json_schema["description"] = description
88
+
89
+ if adk_type_enum == adk_gemini_types.Type.OBJECT:
90
+ properties = getattr(adk_schema, 'properties', None)
91
+ if properties:
92
+ json_schema["properties"] = {
93
+ name: _adk_schema_to_gofannon_json_schema(prop_schema)
94
+ for name, prop_schema in properties.items()
95
+ }
96
+ else:
97
+ json_schema["properties"] = {} # Ensure properties exist for object type
98
+
99
+ items = getattr(adk_schema, 'items', None)
100
+ if adk_type_enum == adk_gemini_types.Type.ARRAY and items:
101
+ json_schema["items"] = _adk_schema_to_gofannon_json_schema(items)
102
+
103
+ required_list = getattr(adk_schema, 'required', None)
104
+ if required_list:
105
+ json_schema["required"] = list(required_list)
106
+
107
+ enum_list = getattr(adk_schema, 'enum', None)
108
+ if enum_list:
109
+ json_schema["enum"] = list(enum_list)
110
+
111
+ # Ensure "properties" field exists if type is "object"
112
+ if json_schema.get("type") == "object" and "properties" not in json_schema:
113
+ json_schema["properties"] = {}
114
+
115
+ return json_schema
116
+
117
+ # Helper for Gofannon JSON Schema to ADK Schema
118
+ JSON_TYPE_TO_ADK_GEMINI_TYPE = {
119
+ "string": adk_gemini_types.Type.STRING,
120
+ "integer": adk_gemini_types.Type.INTEGER,
121
+ "number": adk_gemini_types.Type.NUMBER,
122
+ "boolean": adk_gemini_types.Type.BOOLEAN,
123
+ "array": adk_gemini_types.Type.ARRAY,
124
+ "object": adk_gemini_types.Type.OBJECT,
125
+ "null": adk_gemini_types.Type.TYPE_UNSPECIFIED, # ADK has no 'null' type, unspecified is closest
126
+ }
127
+
128
+ def _gofannon_json_schema_to_adk_schema(json_schema: Dict[str, Any]) -> adk_gemini_types.Schema:
129
+ if not json_schema: # Handles empty dict {} case
130
+ return adk_gemini_types.Schema(type=adk_gemini_types.Type.OBJECT, properties={})
131
+
132
+ adk_schema_kwargs: Dict[str, Any] = {}
133
+
134
+ json_type_val = json_schema.get("type", "object")
135
+ is_nullable = json_schema.get("nullable", False) # Check for explicit "nullable"
136
+
137
+ actual_json_type_str = json_type_val
138
+ if isinstance(json_type_val, list): # Handles type: ["string", "null"]
139
+ if "null" in json_type_val:
140
+ is_nullable = True
141
+ actual_json_type_str = next((t for t in json_type_val if t != "null"), "object")
142
+
143
+ adk_type_enum = JSON_TYPE_TO_ADK_GEMINI_TYPE.get(str(actual_json_type_str).lower(), adk_gemini_types.Type.OBJECT)
144
+ adk_schema_kwargs["type"] = adk_type_enum
145
+ if is_nullable:
146
+ adk_schema_kwargs["nullable"] = True
147
+
148
+ if "description" in json_schema:
149
+ adk_schema_kwargs["description"] = json_schema["description"]
150
+
151
+ if adk_type_enum == adk_gemini_types.Type.OBJECT and "properties" in json_schema:
152
+ adk_schema_kwargs["properties"] = {
153
+ name: _gofannon_json_schema_to_adk_schema(prop_schema)
154
+ for name, prop_schema in json_schema["properties"].items()
155
+ }
156
+ elif adk_type_enum == adk_gemini_types.Type.OBJECT: # Ensure properties for object type
157
+ adk_schema_kwargs["properties"] = {}
158
+
159
+ if adk_type_enum == adk_gemini_types.Type.ARRAY and "items" in json_schema:
160
+ adk_schema_kwargs["items"] = _gofannon_json_schema_to_adk_schema(json_schema["items"])
161
+
162
+ if "required" in json_schema:
163
+ adk_schema_kwargs["required"] = list(json_schema["required"])
164
+
165
+ if "enum" in json_schema:
166
+ adk_schema_kwargs["enum"] = list(json_schema["enum"])
167
+
168
+ return adk_gemini_types.Schema(**adk_schema_kwargs)
169
+
170
+
171
+ class AdkMixin:
172
+ def import_from_adk(self, adk_tool: AdkBaseTool):
173
+ """
174
+ Adapts a google-adk-python tool to the Gofannon BaseTool structure.
175
+
176
+ Args:
177
+ adk_tool: An instance of a class derived from `google.adk.tools.BaseTool`.
178
+ """
179
+ if not _HAS_ADK:
180
+ raise RuntimeError(
181
+ "google-adk-python is not installed. Install with `pip install google-adk`"
182
+ )
183
+ if not isinstance(adk_tool, AdkBaseTool): # type: ignore
184
+ raise TypeError("Input must be an instance of ADK BaseTool.")
185
+
186
+ self.name = adk_tool.name # type: ignore
187
+ self.description = adk_tool.description # type: ignore
188
+
189
+ declaration = None
190
+ # Ensure _get_declaration is callable and attempt to call it
191
+ if hasattr(adk_tool, "_get_declaration") and callable(adk_tool._get_declaration): # type: ignore
192
+ try:
193
+ declaration = adk_tool._get_declaration() # type: ignore
194
+ except Exception as e:
195
+ self.logger.warning(f"Could not get declaration from ADK tool {self.name}: {e}. Assuming no parameters.") # type: ignore
196
+
197
+ gofannon_params_schema: Dict[str, Any] = {"type": "object", "properties": {}}
198
+ if declaration and hasattr(declaration, 'parameters') and declaration.parameters:
199
+ gofannon_params_schema = _adk_schema_to_gofannon_json_schema(declaration.parameters)
200
+
201
+ self.definition = { # type: ignore
202
+ "function": {
203
+ "name": self.name,
204
+ "description": self.description,
205
+ "parameters": gofannon_params_schema
206
+ }
207
+ }
208
+
209
+ # Adapt the execution logic
210
+ if isinstance(adk_tool, AdkFunctionTool) and hasattr(adk_tool, 'func'): # type: ignore
211
+ target_callable = adk_tool.func # type: ignore
212
+ self.fn = target_callable # type: ignore
213
+ elif hasattr(adk_tool, 'run_async') and callable(adk_tool.run_async): # type: ignore
214
+ self.logger.warning( # type: ignore
215
+ f"Importing ADK tool {self.name} that is not a FunctionTool. "
216
+ f"ADK ToolContext features will not be available or may require a dummy context. "
217
+ f"Ensure this tool can operate correctly with args only."
218
+ )
219
+ # This wrapper will become self.fn. If self.fn is async, Gofannon's
220
+ # execute_async can await it directly. Gofannon's sync execute
221
+ # would need to handle running this async fn (e.g., using anyio.run).
222
+ async def adk_run_async_wrapper(**kwargs):
223
+ # This simplified call assumes the tool can function with a None ToolContext
224
+ # or that its core logic doesn't strictly depend on it.
225
+ return await adk_tool.run_async(args=kwargs, tool_context=None) # type: ignore
226
+ self.fn = adk_run_async_wrapper # type: ignore
227
+ else:
228
+ self.logger.error( # type: ignore
229
+ f"ADK tool {self.name} does not have a suitable execution method ('func' or 'run_async')."
230
+ )
231
+ def placeholder_fn(**kwargs):
232
+ raise NotImplementedError(f"Execution for imported ADK tool {self.name} is not available.")
233
+ self.fn = placeholder_fn # type: ignore
234
+
235
+
236
+ def export_to_adk(self) -> AdkBaseTool:
237
+ """
238
+ Converts the Gofannon tool to a google-adk-python compatible tool.
239
+ This typically creates a custom AdkBaseTool derivative that uses the
240
+ Gofannon tool's definition and execution logic.
241
+
242
+ Returns:
243
+ An instance of a `google.adk.tools.BaseTool` derivative.
244
+ """
245
+ if not _HAS_ADK:
246
+ raise RuntimeError(
247
+ "google-adk-python is not installed. Install with `pip install google-adk`"
248
+ )
249
+
250
+ gofannon_def = self.definition.get("function", {}) # type: ignore
251
+ tool_name = gofannon_def.get("name", getattr(self, "name", "gofannon_exported_tool"))
252
+ tool_description = gofannon_def.get("description", getattr(self, "description", "No description provided."))
253
+
254
+ gofannon_params_schema = gofannon_def.get("parameters", {"type": "object", "properties": {}})
255
+
256
+ original_gofannon_fn = self.fn # type: ignore
257
+ is_gofannon_fn_async = inspect.iscoroutinefunction(original_gofannon_fn)
258
+
259
+ # Define a custom ADK Tool class
260
+ class GofannonAdkTool(AdkBaseTool): # type: ignore
261
+ def __init__(self, name, description, gofannon_json_schema, gofannon_exec_fn, is_fn_async):
262
+ super().__init__(name=name, description=description) # type: ignore
263
+ self._gofannon_json_schema = gofannon_json_schema
264
+ self._gofannon_exec_fn = gofannon_exec_fn
265
+ self._is_fn_async = is_fn_async
266
+
267
+ def _get_declaration(self) -> Optional[adk_gemini_types.FunctionDeclaration]: # type: ignore
268
+ adk_params_schema = _gofannon_json_schema_to_adk_schema(self._gofannon_json_schema)
269
+ return adk_gemini_types.FunctionDeclaration( # type: ignore
270
+ name=self.name,
271
+ description=self.description,
272
+ parameters=adk_params_schema
273
+ )
274
+
275
+ async def run_async(self, *, args: Dict[str, Any], tool_context: AdkToolContext) -> Any: # type: ignore
276
+ # The ADK tool_context is available here but the Gofannon fn doesn't expect it.
277
+ # We simply pass the args to the Gofannon function.
278
+ if self._is_fn_async:
279
+ return await self._gofannon_exec_fn(**args)
280
+ else:
281
+ # Gofannon's synchronous fn needs to be run in a thread
282
+ # as ADK's run_async is an async method.
283
+ # Use functools.partial to create a callable with arguments pre-bound.
284
+ func_with_bound_args = functools.partial(self._gofannon_exec_fn, **args)
285
+ return await anyio.to_thread.run_sync(func_with_bound_args)
286
+
287
+ exported_adk_tool = GofannonAdkTool(
288
+ name=tool_name,
289
+ description=tool_description,
290
+ gofannon_json_schema=gofannon_params_schema,
291
+ gofannon_exec_fn=original_gofannon_fn,
292
+ is_fn_async=is_gofannon_fn_async
293
+ )
294
+ return exported_adk_tool
File without changes
@@ -0,0 +1,70 @@
1
+ from ..base import BaseTool
2
+ from ..config import FunctionRegistry, ToolConfig
3
+ import requests
4
+ import logging
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+ """Fetches the text content of a given URL.
9
+
10
+ This tool makes a simple GET request and returns the raw text content.
11
+ It does not render JavaScript or handle complex interactions."""
12
+
13
+ @FunctionRegistry.register
14
+ class GetUrlContent(BaseTool):
15
+ def __init__(self, name="get_url_content"):
16
+ self.name = name
17
+
18
+ @property
19
+ def definition(self):
20
+ return {
21
+ "type": "function",
22
+ "function": {
23
+ "name": self.name,
24
+ "description": (
25
+ "Fetches the text content of a given URL. "
26
+ "This tool makes a simple GET request and returns the raw text content. "
27
+ "It does not render JavaScript or handle complex interactions."
28
+ ),
29
+ "parameters": {
30
+ "type": "object",
31
+ "properties": {
32
+ "url": {
33
+ "type": "string",
34
+ "description": "The URL to fetch content from (e.g., 'https://www.example.com')."
35
+ }
36
+ },
37
+ "required": ["url"]
38
+ }
39
+ }
40
+ }
41
+
42
+ def fn(self, url: str):
43
+ logger.debug(f"Attempting to fetch content from URL: {url}")
44
+ try:
45
+ headers = {
46
+ 'User-Agent': (
47
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
48
+ 'AppleWebKit/537.36 (KHTML, like Gecko) '
49
+ 'Chrome/91.0.4472.124 Safari/537.36'
50
+ )
51
+ }
52
+ response = requests.get(url, headers=headers, timeout=15)
53
+ response.raise_for_status()
54
+ logger.info(f"Successfully fetched content from URL: {url}")
55
+ return response.text
56
+ except requests.exceptions.HTTPError as e:
57
+ logger.error(f"HTTP error fetching URL {url}: {e}")
58
+ return f"Error: HTTP error - {e}"
59
+ except requests.exceptions.ConnectionError as e:
60
+ logger.error(f"Connection error fetching URL {url}: {e}")
61
+ return f"Error: Connection error - {e}"
62
+ except requests.exceptions.Timeout as e:
63
+ logger.error(f"Timeout fetching URL {url}: {e}")
64
+ return f"Error: Timeout - {e}"
65
+ except requests.exceptions.RequestException as e:
66
+ logger.error(f"Request error fetching URL {url}: {e}")
67
+ return f"Error: Request error - {e}"
68
+ except Exception as e:
69
+ logger.error(f"Unexpected error fetching URL {url}: {e}")
70
+ return f"Error: Unexpected error - {e}"
File without changes
@@ -0,0 +1,74 @@
1
+ from ..base import BaseTool
2
+ from ..config import FunctionRegistry, ToolConfig
3
+ import logging
4
+ import requests
5
+ import os
6
+ import pdfplumber
7
+ from pdfminer.pdfparser import PDFSyntaxError
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ """
12
+ A tool for reading the text content from a PDF file.
13
+
14
+ This class provides a function that takes a file path to a PDF as input
15
+ and returns its text content as a string.
16
+ """
17
+
18
+ @FunctionRegistry.register
19
+ class ReadPdf(BaseTool) :
20
+ def __init__(self, name="pdf_reader"):
21
+ super().__init__()
22
+ self.name=name
23
+
24
+ @property
25
+ def definition(self):
26
+ return{
27
+ "type": "function",
28
+ "function": {
29
+ "name": self.name,
30
+ "description": "Read teh text content from a PDF file",
31
+ "parameters": {
32
+ "type": "object",
33
+ "properties": {
34
+ "file_path": {
35
+ "type": "string",
36
+ "description": "The local path to the PDF file to be read."
37
+ }
38
+ },
39
+ "required": ["file_path"]
40
+ }
41
+ }
42
+ }
43
+
44
+ def fn(self, file_path: str) -> str :
45
+ logger.debug(f"Reading PDF file: {file_path}")
46
+ try:
47
+ if not os.path.exists(file_path):
48
+ logger.error(f"File not found: {file_path}")
49
+ return f"Error: File not found at path '{file_path}'."
50
+ if not file_path.lower().endswith(".pdf"):
51
+ logger.error(f"File is not a PDF: {file_path}")
52
+ return f"Error: File '{file_path}' is not a PDF."
53
+
54
+ text_content = []
55
+ with pdfplumber.open(file_path) as pdf:
56
+ for page_num, page in enumerate(pdf.pages):
57
+ page_text = page.extract_text()
58
+ if page_text:
59
+ text_content.append(page_text)
60
+ else:
61
+ logger.debug(f"No text extracted from page {page_num+1} of {file_path}")
62
+
63
+ if not text_content:
64
+ logger.warning(f"No text could be extracted from the PDF: {file_path}")
65
+ return "No text content could be extracted from this PDF."
66
+
67
+ return "\n".join(text_content)
68
+
69
+ except PDFSyntaxError:
70
+ logger.error(f"Error parsing PDF (syntax error): {file_path}")
71
+ return f"Error: Could not parse PDF file '{file_path}'. It might be corrupted or not a valid PDF."
72
+ except Exception as e:
73
+ logger.error(f"An unexpected error occurred while reading PDF '{file_path}': {e}", exc_info=True)
74
+ return f"Error reading PDF file '{file_path}': {e}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: gofannon
3
- Version: 0.25.20
3
+ Version: 0.25.22
4
4
  Summary: A collection of tools for LLMs
5
5
  License: ASFv2
6
6
  Author: Trevor Grant
@@ -52,7 +52,7 @@ functionality for various tasks.
52
52
  ## 🌟🌟 Features 🌟🌟
53
53
 
54
54
  1. Cross-Framework Compatibility (Import From/Export To Multiple Frameworks)
55
- - **Current:** `smolagents`, LangChain, AWS Bedrock
55
+ - **Current:** `smolagents`, LangChain, AWS Bedrock, Google ADK
56
56
  - **Currently Being Developed:** [Up To Date List](https://github.com/The-AI-Alliance/gofannon/issues?q=is%3Aissue%20state%3Aopen%20label%3Aframework%20assignee:*)
57
57
  - **In The Roadmap:** [Up To Date List](https://github.com/The-AI-Alliance/gofannon/issues?q=is%3Aissue%20state%3Aopen%20label%3Aframework%20no%3Aassignee)
58
58
  2. A Robust Collection of Tools
@@ -2,7 +2,8 @@ gofannon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  gofannon/arxiv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  gofannon/arxiv/get_article.py,sha256=SRGTXFXdXdXTIOLZKWUTXxZEYEqZFWFJEV2nTsU5qqU,1167
4
4
  gofannon/arxiv/search.py,sha256=37Zx1y2vAX1xYIKaAxzBGXE3qPHUZdAD2XR0H1Acs-4,4225
5
- gofannon/base/__init__.py,sha256=wnTkASBszxkZiWugQOgvSdAghFFBUwxzRzz7wTMxg3c,3757
5
+ gofannon/base/__init__.py,sha256=n2tWf7udXSXfREsxXD0E8kOY--X-ffGTNsdMwk2V33A,3814
6
+ gofannon/base/adk_mixin.py,sha256=AR9dd9sdQ1KSrs2gXVExl7_Z4DUG3xwf3rVa2q66Ok0,13520
6
7
  gofannon/base/bedrock.py,sha256=Z2c36R8jaIusgpmegbYVz2eR7lDBc0IhTtwiqUGOcT4,25646
7
8
  gofannon/base/langchain.py,sha256=25z9opy7E7qWP-DSn6oYAqKDg8i21az-kAKrsYLfyiQ,2704
8
9
  gofannon/base/langflow.py,sha256=0WfNJ9MnndyLJ-yUAStIuXZpCzOPItsGKgtxdNifmLM,3833
@@ -20,6 +21,8 @@ gofannon/file/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
21
  gofannon/file/list_directory.py,sha256=Jw0F50_hdtyDSFBmcy9e8F4KajtsPyT8Gsm_eyjMUuQ,2679
21
22
  gofannon/file/read_file.py,sha256=kYf-4aGCHLj-D-XQs0YBEnbB1MbIccgcWbiLnVXidp4,1669
22
23
  gofannon/file/write_file.py,sha256=fQ5P4cqZKdoq8Bk7nys2Esau0Q5WvbeY8srGvfx36NQ,1495
24
+ gofannon/get_url_content/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ gofannon/get_url_content/get_url_content.py,sha256=Bj1TUUhaAB6Ts783rCEJQxTd-gq-eWFuT-Ao6Nx3CKo,2754
23
26
  gofannon/github/__init__.py,sha256=VFw4sJIt4Zc0-__eYnksN8Ku9qMhbPpHJEkXMWUiD30,4
24
27
  gofannon/github/clone_repo.py,sha256=UNXh1JaZkzK94REJUfQrBAhF66ncFWkzcZj34Si34cI,2287
25
28
  gofannon/github/commit_file.py,sha256=jdQGQHbrZx4521XgTbx5N0Ss8fDyl7hvp9sjDW15v9U,2573
@@ -42,6 +45,8 @@ gofannon/open_notify_space/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74
42
45
  gofannon/open_notify_space/iss_locator.py,sha256=STLNSD5HriRR6grpRpiTRDbqVRtWMPVoGuV8SygHGNY,4734
43
46
  gofannon/orchestration/__init__.py,sha256=_p_XhWHgOIgiamFSGwFUqrnBlIYDvQMq5L5mxJvxiks,5121
44
47
  gofannon/orchestration/firebase_wrapper.py,sha256=jXqUcIoKuTC_1ZffN3v1DN9X6of-OuMKWP8ZzQ-wHOU,1394
48
+ gofannon/pdf_reader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
+ gofannon/pdf_reader/pdf_reader.py,sha256=yBFzB8V_dMyZVqFm7zMiuD7X-VHb0dlSLNo3VlFCOzY,2808
45
50
  gofannon/reasoning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
51
  gofannon/reasoning/base.py,sha256=D-4JHJqUlqgwMNOkKU0BHYA4GEWwNgPlLxKYHX0FVyg,1494
47
52
  gofannon/reasoning/hierarchical_cot.py,sha256=e8ZgMbyJQ0wCBEmv7QJqFv7l3XxTMwDYupGxJ7EF6t8,11516
@@ -64,7 +69,7 @@ gofannon/simpler_grants_gov/search_base.py,sha256=ask8ecAOQ9jZulr8iDxdfQZgSC_Eyx
64
69
  gofannon/simpler_grants_gov/search_opportunities.py,sha256=jZD64VqFIW36dBdAshOOQmywzLqBZyB3wLtA_C95sa8,19931
65
70
  gofannon/wikipedia/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
71
  gofannon/wikipedia/wikipedia_lookup.py,sha256=J6wKPbSivCF7cccaiRaJW1o0VqNhQAGfrh5U1ULLesg,2869
67
- gofannon-0.25.20.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
68
- gofannon-0.25.20.dist-info/METADATA,sha256=n5vCujMhTpr9mRxBrV-VakPK3zAxcyvWIBr7bWn6g8o,5415
69
- gofannon-0.25.20.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
70
- gofannon-0.25.20.dist-info/RECORD,,
72
+ gofannon-0.25.22.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
73
+ gofannon-0.25.22.dist-info/METADATA,sha256=Ds3UuiBNhtLDGHhiEviSUONX82NbxzjVAQ2YudS0yU4,5427
74
+ gofannon-0.25.22.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
75
+ gofannon-0.25.22.dist-info/RECORD,,