agentr 0.1.3__py3-none-any.whl → 0.1.4__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.
- agentr/__init__.py +1 -1
- agentr/application.py +56 -56
- agentr/applications/github/app.py +55 -51
- agentr/applications/google_calendar/app.py +73 -73
- agentr/applications/google_mail/app.py +67 -67
- agentr/applications/reddit/app.py +29 -29
- agentr/applications/resend/app.py +43 -43
- agentr/applications/tavily/app.py +57 -57
- agentr/applications/zenquotes/app.py +20 -20
- agentr/cli.py +75 -58
- agentr/exceptions.py +5 -0
- agentr/integration.py +98 -91
- agentr/server.py +105 -105
- agentr/store.py +70 -70
- agentr/test.py +37 -37
- agentr/utils/openapi.py +184 -184
- agentr-0.1.4.dist-info/METADATA +156 -0
- agentr-0.1.4.dist-info/RECORD +22 -0
- agentr-0.1.3.dist-info/METADATA +0 -10
- agentr-0.1.3.dist-info/RECORD +0 -21
- {agentr-0.1.3.dist-info → agentr-0.1.4.dist-info}/WHEEL +0 -0
- {agentr-0.1.3.dist-info → agentr-0.1.4.dist-info}/entry_points.txt +0 -0
    
        agentr/utils/openapi.py
    CHANGED
    
    | @@ -1,185 +1,185 @@ | |
| 1 | 
            -
            import json
         | 
| 2 | 
            -
            import yaml
         | 
| 3 | 
            -
            from pathlib import Path
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            def load_schema(path: Path):
         | 
| 6 | 
            -
                if path.suffix == '.yaml':
         | 
| 7 | 
            -
                    type = 'yaml'
         | 
| 8 | 
            -
                else:
         | 
| 9 | 
            -
                    type = 'json'
         | 
| 10 | 
            -
                with open(path, 'r') as f:
         | 
| 11 | 
            -
                    if type == 'yaml':
         | 
| 12 | 
            -
                        return yaml.safe_load(f)
         | 
| 13 | 
            -
                    else:
         | 
| 14 | 
            -
                        return json.load(f)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            def generate_api_client(schema):
         | 
| 17 | 
            -
                """
         | 
| 18 | 
            -
                Generate a Python API client class from an OpenAPI schema.
         | 
| 19 | 
            -
                
         | 
| 20 | 
            -
                Args:
         | 
| 21 | 
            -
                    schema (dict): The OpenAPI schema as a dictionary.
         | 
| 22 | 
            -
                
         | 
| 23 | 
            -
                Returns:
         | 
| 24 | 
            -
                    str: A string containing the Python code for the API client class.
         | 
| 25 | 
            -
                """
         | 
| 26 | 
            -
                methods = []
         | 
| 27 | 
            -
                
         | 
| 28 | 
            -
                # Iterate over paths and their operations
         | 
| 29 | 
            -
                for path, path_info in schema.get('paths', {}).items():
         | 
| 30 | 
            -
                    for method in path_info:
         | 
| 31 | 
            -
                        if method in ['get', 'post', 'put', 'delete', 'patch', 'options', 'head']:
         | 
| 32 | 
            -
                            operation = path_info[method]
         | 
| 33 | 
            -
                            method_code = generate_method_code(path, method, operation)
         | 
| 34 | 
            -
                            methods.append(method_code)
         | 
| 35 | 
            -
                
         | 
| 36 | 
            -
                # Construct the class code
         | 
| 37 | 
            -
                class_code = (
         | 
| 38 | 
            -
                    "import requests\n\n"
         | 
| 39 | 
            -
                    "class APIClient:\n"
         | 
| 40 | 
            -
                    "    def __init__(self, base_url):\n"
         | 
| 41 | 
            -
                    "        self.base_url = base_url\n\n" +
         | 
| 42 | 
            -
                    '\n\n'.join(methods)
         | 
| 43 | 
            -
                )
         | 
| 44 | 
            -
                return class_code
         | 
| 45 | 
            -
             | 
| 46 | 
            -
            def generate_method_code(path, method, operation):
         | 
| 47 | 
            -
                """
         | 
| 48 | 
            -
                Generate the code for a single API method.
         | 
| 49 | 
            -
                
         | 
| 50 | 
            -
                Args:
         | 
| 51 | 
            -
                    path (str): The API path (e.g., '/users/{user_id}').
         | 
| 52 | 
            -
                    method (str): The HTTP method (e.g., 'get').
         | 
| 53 | 
            -
                    operation (dict): The operation details from the schema.
         | 
| 54 | 
            -
                
         | 
| 55 | 
            -
                Returns:
         | 
| 56 | 
            -
                    str: The Python code for the method.
         | 
| 57 | 
            -
                """
         | 
| 58 | 
            -
                # Determine function name
         | 
| 59 | 
            -
                if 'operationId' in operation:
         | 
| 60 | 
            -
                    func_name = operation['operationId']
         | 
| 61 | 
            -
                else:
         | 
| 62 | 
            -
                    # Generate name from path and method
         | 
| 63 | 
            -
                    path_parts = path.strip('/').split('/')
         | 
| 64 | 
            -
                    name_parts = [method]
         | 
| 65 | 
            -
                    for part in path_parts:
         | 
| 66 | 
            -
                        if part.startswith('{') and part.endswith('}'):
         | 
| 67 | 
            -
                            name_parts.append('by_' + part[1:-1])
         | 
| 68 | 
            -
                        else:
         | 
| 69 | 
            -
                            name_parts.append(part)
         | 
| 70 | 
            -
                    func_name = '_'.join(name_parts).replace('-', '_').lower()
         | 
| 71 | 
            -
                
         | 
| 72 | 
            -
                # Get parameters and request body
         | 
| 73 | 
            -
                parameters = operation.get('parameters', [])
         | 
| 74 | 
            -
                has_body = 'requestBody' in operation
         | 
| 75 | 
            -
                body_required = has_body and operation['requestBody'].get('required', False)
         | 
| 76 | 
            -
                
         | 
| 77 | 
            -
                # Build function arguments
         | 
| 78 | 
            -
                args = []
         | 
| 79 | 
            -
                for param in parameters:
         | 
| 80 | 
            -
                    if param.get('required', False):
         | 
| 81 | 
            -
                        args.append(param['name'])
         | 
| 82 | 
            -
                    else:
         | 
| 83 | 
            -
                        args.append(f"{param['name']}=None")
         | 
| 84 | 
            -
                if has_body:
         | 
| 85 | 
            -
                    args.append('body' if body_required else 'body=None')
         | 
| 86 | 
            -
                signature = f"def {func_name}(self, {', '.join(args)}):"
         | 
| 87 | 
            -
                
         | 
| 88 | 
            -
                # Build method body
         | 
| 89 | 
            -
                body_lines = []
         | 
| 90 | 
            -
                
         | 
| 91 | 
            -
                # Path parameters
         | 
| 92 | 
            -
                path_params = [p for p in parameters if p['in'] == 'path']
         | 
| 93 | 
            -
                path_params_dict = ', '.join([f"'{p['name']}': {p['name']}" for p in path_params])
         | 
| 94 | 
            -
                body_lines.append(f"    path_params = {{{path_params_dict}}}")
         | 
| 95 | 
            -
                
         | 
| 96 | 
            -
                # Query parameters
         | 
| 97 | 
            -
                query_params = [p for p in parameters if p['in'] == 'query']
         | 
| 98 | 
            -
                query_params_items = ', '.join([f"('{p['name']}', {p['name']})" for p in query_params])
         | 
| 99 | 
            -
                body_lines.append(
         | 
| 100 | 
            -
                    f"    query_params = {{k: v for k, v in [{query_params_items}] if v is not None}}"
         | 
| 101 | 
            -
                )
         | 
| 102 | 
            -
                
         | 
| 103 | 
            -
                # Format URL
         | 
| 104 | 
            -
                body_lines.append(f"    url = f\"{{self.base_url}}{path}\".format_map(path_params)")
         | 
| 105 | 
            -
                
         | 
| 106 | 
            -
                # Make HTTP request
         | 
| 107 | 
            -
                method_func = method.lower()
         | 
| 108 | 
            -
                if has_body:
         | 
| 109 | 
            -
                    body_lines.append("    if body is not None:")
         | 
| 110 | 
            -
                    body_lines.append(f"        response = requests.{method_func}(url, params=query_params, json=body)")
         | 
| 111 | 
            -
                    body_lines.append("    else:")
         | 
| 112 | 
            -
                    body_lines.append(f"        response = requests.{method_func}(url, params=query_params)")
         | 
| 113 | 
            -
                else:
         | 
| 114 | 
            -
                    body_lines.append(f"    response = requests.{method_func}(url, params=query_params)")
         | 
| 115 | 
            -
                
         | 
| 116 | 
            -
                # Handle response
         | 
| 117 | 
            -
                body_lines.append("    response.raise_for_status()")
         | 
| 118 | 
            -
                body_lines.append("    return response.json()")
         | 
| 119 | 
            -
                
         | 
| 120 | 
            -
                return signature + '\n' + '\n'.join(body_lines)
         | 
| 121 | 
            -
             | 
| 122 | 
            -
            # Example usage
         | 
| 123 | 
            -
            if __name__ == "__main__":
         | 
| 124 | 
            -
                # Sample OpenAPI schema
         | 
| 125 | 
            -
                schema = {
         | 
| 126 | 
            -
                    "paths": {
         | 
| 127 | 
            -
                        "/users": {
         | 
| 128 | 
            -
                            "get": {
         | 
| 129 | 
            -
                                "summary": "Get a list of users",
         | 
| 130 | 
            -
                                "parameters": [
         | 
| 131 | 
            -
                                    {
         | 
| 132 | 
            -
                                        "name": "limit",
         | 
| 133 | 
            -
                                        "in": "query",
         | 
| 134 | 
            -
                                        "required": False,
         | 
| 135 | 
            -
                                        "schema": {"type": "integer"}
         | 
| 136 | 
            -
                                    }
         | 
| 137 | 
            -
                                ],
         | 
| 138 | 
            -
                                "responses": {
         | 
| 139 | 
            -
                                    "200": {
         | 
| 140 | 
            -
                                        "description": "A list of users",
         | 
| 141 | 
            -
                                        "content": {"application/json": {"schema": {"type": "array"}}}
         | 
| 142 | 
            -
                                    }
         | 
| 143 | 
            -
                                }
         | 
| 144 | 
            -
                            },
         | 
| 145 | 
            -
                            "post": {
         | 
| 146 | 
            -
                                "summary": "Create a user",
         | 
| 147 | 
            -
                                "requestBody": {
         | 
| 148 | 
            -
                                    "required": True,
         | 
| 149 | 
            -
                                    "content": {
         | 
| 150 | 
            -
                                        "application/json": {
         | 
| 151 | 
            -
                                            "schema": {
         | 
| 152 | 
            -
                                                "type": "object",
         | 
| 153 | 
            -
                                                "properties": {"name": {"type": "string"}}
         | 
| 154 | 
            -
                                            }
         | 
| 155 | 
            -
                                        }
         | 
| 156 | 
            -
                                    }
         | 
| 157 | 
            -
                                },
         | 
| 158 | 
            -
                                "responses": {
         | 
| 159 | 
            -
                                    "201": {"description": "User created"}
         | 
| 160 | 
            -
                                }
         | 
| 161 | 
            -
                            }
         | 
| 162 | 
            -
                        },
         | 
| 163 | 
            -
                        "/users/{user_id}": {
         | 
| 164 | 
            -
                            "get": {
         | 
| 165 | 
            -
                                "summary": "Get a user by ID",
         | 
| 166 | 
            -
                                "parameters": [
         | 
| 167 | 
            -
                                    {
         | 
| 168 | 
            -
                                        "name": "user_id",
         | 
| 169 | 
            -
                                        "in": "path",
         | 
| 170 | 
            -
                                        "required": True,
         | 
| 171 | 
            -
                                        "schema": {"type": "string"}
         | 
| 172 | 
            -
                                    }
         | 
| 173 | 
            -
                                ],
         | 
| 174 | 
            -
                                "responses": {
         | 
| 175 | 
            -
                                    "200": {"description": "User details"}
         | 
| 176 | 
            -
                                }
         | 
| 177 | 
            -
                            }
         | 
| 178 | 
            -
                        }
         | 
| 179 | 
            -
                    }
         | 
| 180 | 
            -
                }
         | 
| 181 | 
            -
                
         | 
| 182 | 
            -
             | 
| 183 | 
            -
                schema = load_schema('openapi.yaml')
         | 
| 184 | 
            -
                code = generate_api_client(schema)
         | 
| 1 | 
            +
            import json
         | 
| 2 | 
            +
            import yaml
         | 
| 3 | 
            +
            from pathlib import Path
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            def load_schema(path: Path):
         | 
| 6 | 
            +
                if path.suffix == '.yaml':
         | 
| 7 | 
            +
                    type = 'yaml'
         | 
| 8 | 
            +
                else:
         | 
| 9 | 
            +
                    type = 'json'
         | 
| 10 | 
            +
                with open(path, 'r') as f:
         | 
| 11 | 
            +
                    if type == 'yaml':
         | 
| 12 | 
            +
                        return yaml.safe_load(f)
         | 
| 13 | 
            +
                    else:
         | 
| 14 | 
            +
                        return json.load(f)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            def generate_api_client(schema):
         | 
| 17 | 
            +
                """
         | 
| 18 | 
            +
                Generate a Python API client class from an OpenAPI schema.
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                Args:
         | 
| 21 | 
            +
                    schema (dict): The OpenAPI schema as a dictionary.
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                Returns:
         | 
| 24 | 
            +
                    str: A string containing the Python code for the API client class.
         | 
| 25 | 
            +
                """
         | 
| 26 | 
            +
                methods = []
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                # Iterate over paths and their operations
         | 
| 29 | 
            +
                for path, path_info in schema.get('paths', {}).items():
         | 
| 30 | 
            +
                    for method in path_info:
         | 
| 31 | 
            +
                        if method in ['get', 'post', 'put', 'delete', 'patch', 'options', 'head']:
         | 
| 32 | 
            +
                            operation = path_info[method]
         | 
| 33 | 
            +
                            method_code = generate_method_code(path, method, operation)
         | 
| 34 | 
            +
                            methods.append(method_code)
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                # Construct the class code
         | 
| 37 | 
            +
                class_code = (
         | 
| 38 | 
            +
                    "import requests\n\n"
         | 
| 39 | 
            +
                    "class APIClient:\n"
         | 
| 40 | 
            +
                    "    def __init__(self, base_url):\n"
         | 
| 41 | 
            +
                    "        self.base_url = base_url\n\n" +
         | 
| 42 | 
            +
                    '\n\n'.join(methods)
         | 
| 43 | 
            +
                )
         | 
| 44 | 
            +
                return class_code
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            def generate_method_code(path, method, operation):
         | 
| 47 | 
            +
                """
         | 
| 48 | 
            +
                Generate the code for a single API method.
         | 
| 49 | 
            +
                
         | 
| 50 | 
            +
                Args:
         | 
| 51 | 
            +
                    path (str): The API path (e.g., '/users/{user_id}').
         | 
| 52 | 
            +
                    method (str): The HTTP method (e.g., 'get').
         | 
| 53 | 
            +
                    operation (dict): The operation details from the schema.
         | 
| 54 | 
            +
                
         | 
| 55 | 
            +
                Returns:
         | 
| 56 | 
            +
                    str: The Python code for the method.
         | 
| 57 | 
            +
                """
         | 
| 58 | 
            +
                # Determine function name
         | 
| 59 | 
            +
                if 'operationId' in operation:
         | 
| 60 | 
            +
                    func_name = operation['operationId']
         | 
| 61 | 
            +
                else:
         | 
| 62 | 
            +
                    # Generate name from path and method
         | 
| 63 | 
            +
                    path_parts = path.strip('/').split('/')
         | 
| 64 | 
            +
                    name_parts = [method]
         | 
| 65 | 
            +
                    for part in path_parts:
         | 
| 66 | 
            +
                        if part.startswith('{') and part.endswith('}'):
         | 
| 67 | 
            +
                            name_parts.append('by_' + part[1:-1])
         | 
| 68 | 
            +
                        else:
         | 
| 69 | 
            +
                            name_parts.append(part)
         | 
| 70 | 
            +
                    func_name = '_'.join(name_parts).replace('-', '_').lower()
         | 
| 71 | 
            +
                
         | 
| 72 | 
            +
                # Get parameters and request body
         | 
| 73 | 
            +
                parameters = operation.get('parameters', [])
         | 
| 74 | 
            +
                has_body = 'requestBody' in operation
         | 
| 75 | 
            +
                body_required = has_body and operation['requestBody'].get('required', False)
         | 
| 76 | 
            +
                
         | 
| 77 | 
            +
                # Build function arguments
         | 
| 78 | 
            +
                args = []
         | 
| 79 | 
            +
                for param in parameters:
         | 
| 80 | 
            +
                    if param.get('required', False):
         | 
| 81 | 
            +
                        args.append(param['name'])
         | 
| 82 | 
            +
                    else:
         | 
| 83 | 
            +
                        args.append(f"{param['name']}=None")
         | 
| 84 | 
            +
                if has_body:
         | 
| 85 | 
            +
                    args.append('body' if body_required else 'body=None')
         | 
| 86 | 
            +
                signature = f"def {func_name}(self, {', '.join(args)}):"
         | 
| 87 | 
            +
                
         | 
| 88 | 
            +
                # Build method body
         | 
| 89 | 
            +
                body_lines = []
         | 
| 90 | 
            +
                
         | 
| 91 | 
            +
                # Path parameters
         | 
| 92 | 
            +
                path_params = [p for p in parameters if p['in'] == 'path']
         | 
| 93 | 
            +
                path_params_dict = ', '.join([f"'{p['name']}': {p['name']}" for p in path_params])
         | 
| 94 | 
            +
                body_lines.append(f"    path_params = {{{path_params_dict}}}")
         | 
| 95 | 
            +
                
         | 
| 96 | 
            +
                # Query parameters
         | 
| 97 | 
            +
                query_params = [p for p in parameters if p['in'] == 'query']
         | 
| 98 | 
            +
                query_params_items = ', '.join([f"('{p['name']}', {p['name']})" for p in query_params])
         | 
| 99 | 
            +
                body_lines.append(
         | 
| 100 | 
            +
                    f"    query_params = {{k: v for k, v in [{query_params_items}] if v is not None}}"
         | 
| 101 | 
            +
                )
         | 
| 102 | 
            +
                
         | 
| 103 | 
            +
                # Format URL
         | 
| 104 | 
            +
                body_lines.append(f"    url = f\"{{self.base_url}}{path}\".format_map(path_params)")
         | 
| 105 | 
            +
                
         | 
| 106 | 
            +
                # Make HTTP request
         | 
| 107 | 
            +
                method_func = method.lower()
         | 
| 108 | 
            +
                if has_body:
         | 
| 109 | 
            +
                    body_lines.append("    if body is not None:")
         | 
| 110 | 
            +
                    body_lines.append(f"        response = requests.{method_func}(url, params=query_params, json=body)")
         | 
| 111 | 
            +
                    body_lines.append("    else:")
         | 
| 112 | 
            +
                    body_lines.append(f"        response = requests.{method_func}(url, params=query_params)")
         | 
| 113 | 
            +
                else:
         | 
| 114 | 
            +
                    body_lines.append(f"    response = requests.{method_func}(url, params=query_params)")
         | 
| 115 | 
            +
                
         | 
| 116 | 
            +
                # Handle response
         | 
| 117 | 
            +
                body_lines.append("    response.raise_for_status()")
         | 
| 118 | 
            +
                body_lines.append("    return response.json()")
         | 
| 119 | 
            +
                
         | 
| 120 | 
            +
                return signature + '\n' + '\n'.join(body_lines)
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            # Example usage
         | 
| 123 | 
            +
            if __name__ == "__main__":
         | 
| 124 | 
            +
                # Sample OpenAPI schema
         | 
| 125 | 
            +
                schema = {
         | 
| 126 | 
            +
                    "paths": {
         | 
| 127 | 
            +
                        "/users": {
         | 
| 128 | 
            +
                            "get": {
         | 
| 129 | 
            +
                                "summary": "Get a list of users",
         | 
| 130 | 
            +
                                "parameters": [
         | 
| 131 | 
            +
                                    {
         | 
| 132 | 
            +
                                        "name": "limit",
         | 
| 133 | 
            +
                                        "in": "query",
         | 
| 134 | 
            +
                                        "required": False,
         | 
| 135 | 
            +
                                        "schema": {"type": "integer"}
         | 
| 136 | 
            +
                                    }
         | 
| 137 | 
            +
                                ],
         | 
| 138 | 
            +
                                "responses": {
         | 
| 139 | 
            +
                                    "200": {
         | 
| 140 | 
            +
                                        "description": "A list of users",
         | 
| 141 | 
            +
                                        "content": {"application/json": {"schema": {"type": "array"}}}
         | 
| 142 | 
            +
                                    }
         | 
| 143 | 
            +
                                }
         | 
| 144 | 
            +
                            },
         | 
| 145 | 
            +
                            "post": {
         | 
| 146 | 
            +
                                "summary": "Create a user",
         | 
| 147 | 
            +
                                "requestBody": {
         | 
| 148 | 
            +
                                    "required": True,
         | 
| 149 | 
            +
                                    "content": {
         | 
| 150 | 
            +
                                        "application/json": {
         | 
| 151 | 
            +
                                            "schema": {
         | 
| 152 | 
            +
                                                "type": "object",
         | 
| 153 | 
            +
                                                "properties": {"name": {"type": "string"}}
         | 
| 154 | 
            +
                                            }
         | 
| 155 | 
            +
                                        }
         | 
| 156 | 
            +
                                    }
         | 
| 157 | 
            +
                                },
         | 
| 158 | 
            +
                                "responses": {
         | 
| 159 | 
            +
                                    "201": {"description": "User created"}
         | 
| 160 | 
            +
                                }
         | 
| 161 | 
            +
                            }
         | 
| 162 | 
            +
                        },
         | 
| 163 | 
            +
                        "/users/{user_id}": {
         | 
| 164 | 
            +
                            "get": {
         | 
| 165 | 
            +
                                "summary": "Get a user by ID",
         | 
| 166 | 
            +
                                "parameters": [
         | 
| 167 | 
            +
                                    {
         | 
| 168 | 
            +
                                        "name": "user_id",
         | 
| 169 | 
            +
                                        "in": "path",
         | 
| 170 | 
            +
                                        "required": True,
         | 
| 171 | 
            +
                                        "schema": {"type": "string"}
         | 
| 172 | 
            +
                                    }
         | 
| 173 | 
            +
                                ],
         | 
| 174 | 
            +
                                "responses": {
         | 
| 175 | 
            +
                                    "200": {"description": "User details"}
         | 
| 176 | 
            +
                                }
         | 
| 177 | 
            +
                            }
         | 
| 178 | 
            +
                        }
         | 
| 179 | 
            +
                    }
         | 
| 180 | 
            +
                }
         | 
| 181 | 
            +
                
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                schema = load_schema('openapi.yaml')
         | 
| 184 | 
            +
                code = generate_api_client(schema)
         | 
| 185 185 | 
             
                print(code)
         | 
| @@ -0,0 +1,156 @@ | |
| 1 | 
            +
            Metadata-Version: 2.4
         | 
| 2 | 
            +
            Name: agentr
         | 
| 3 | 
            +
            Version: 0.1.4
         | 
| 4 | 
            +
            Summary: Add your description here
         | 
| 5 | 
            +
            Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
         | 
| 6 | 
            +
            Requires-Python: >=3.11
         | 
| 7 | 
            +
            Requires-Dist: loguru>=0.7.3
         | 
| 8 | 
            +
            Requires-Dist: mcp>=1.5.0
         | 
| 9 | 
            +
            Requires-Dist: pyyaml>=6.0.2
         | 
| 10 | 
            +
            Requires-Dist: typer>=0.15.2
         | 
| 11 | 
            +
            Description-Content-Type: text/markdown
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # AgentR
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            AgentR is a Python framework for building powerful agent applications with integrated third-party services. It provides a clean abstraction for incorporating various API services as "applications" into your agent workflow.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## 🌟 Features
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            - **Simplified API Integration**: Connect to services like GitHub, Google Calendar, Gmail, Reddit, Tavily, and more with minimal code
         | 
| 20 | 
            +
            - **Authentication Handling**: Built-in support for API keys and OAuth-based authentication flows
         | 
| 21 | 
            +
            - **Extensible Architecture**: Easily build and add new app integrations with minimal boilerplate
         | 
| 22 | 
            +
            - **MCP (Model Context Protocol) Integration**: Seamlessly works with MCP server architecture
         | 
| 23 | 
            +
            - **Credential Management**: Flexible storage options for API credentials with memory and environment-based implementations
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            ## 🔧 Installation
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Install AgentR using pip:
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            ```bash
         | 
| 30 | 
            +
            pip install agentr
         | 
| 31 | 
            +
            ```
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            ## 🚀 Quick Start
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            ### 1. Get an API Key
         | 
| 36 | 
            +
            Before using AgentR with services that require authorization (like GitHub, Gmail, etc.), you'll need an AgentR API key:
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            Visit https://agentr.dev to create an account
         | 
| 39 | 
            +
            Generate an API key from your dashboard
         | 
| 40 | 
            +
            Set it as an environment variable or include it directly in your code:
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            ```bash
         | 
| 43 | 
            +
            export AGENTR_API_KEY="your_api_key_here"
         | 
| 44 | 
            +
            ```
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            ### 2. Create a basic server
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            ```bash
         | 
| 49 | 
            +
            from agentr.server import TestServer
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            # Define your applications list
         | 
| 52 | 
            +
            apps_list = [
         | 
| 53 | 
            +
                {
         | 
| 54 | 
            +
                    "name": "tavily",
         | 
| 55 | 
            +
                    "integration": {
         | 
| 56 | 
            +
                        "name": "tavily_api_key",
         | 
| 57 | 
            +
                        "type": "api_key",
         | 
| 58 | 
            +
                        "store": {
         | 
| 59 | 
            +
                            "type": "environment",
         | 
| 60 | 
            +
                        }
         | 
| 61 | 
            +
                    },        
         | 
| 62 | 
            +
                },
         | 
| 63 | 
            +
                {
         | 
| 64 | 
            +
                    "name": "zenquotes",
         | 
| 65 | 
            +
                    "integration": None
         | 
| 66 | 
            +
                },
         | 
| 67 | 
            +
                {
         | 
| 68 | 
            +
                    "name": "github",
         | 
| 69 | 
            +
                    "integration": {
         | 
| 70 | 
            +
                        "name": "github",
         | 
| 71 | 
            +
                        "type": "agentr",
         | 
| 72 | 
            +
                    }
         | 
| 73 | 
            +
                }
         | 
| 74 | 
            +
            ]
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            # Create a server with these applications
         | 
| 77 | 
            +
            server = TestServer(name="My Agent Server", description="A server for my agent apps", apps_list=apps_list)
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            # Run the server
         | 
| 80 | 
            +
            if __name__ == "__main__":
         | 
| 81 | 
            +
                server.run()
         | 
| 82 | 
            +
            ```
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            ## 🧩 Available Applications
         | 
| 85 | 
            +
            AgentR comes with several pre-built applications:
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            | Application | Description | Authentication Type |
         | 
| 88 | 
            +
            |-------------|-------------|---------------------|
         | 
| 89 | 
            +
            | GitHub | Star repositories and more | OAuth (AgentR) |
         | 
| 90 | 
            +
            | Google Calendar | Retrieve calendar events | OAuth (AgentR) |
         | 
| 91 | 
            +
            | Gmail | Send emails | OAuth (AgentR) |
         | 
| 92 | 
            +
            | Reddit | Access Reddit data | OAuth (AgentR) |
         | 
| 93 | 
            +
            | Resend | Send emails via Resend API | API Key |
         | 
| 94 | 
            +
            | Tavily | Web search capabilities | API Key |
         | 
| 95 | 
            +
            | ZenQuotes | Get inspirational quotes | None |
         | 
| 96 | 
            +
             | 
| 97 | 
            +
            > **Note**: More applications are coming soon! Stay tuned for updates to our application catalog.
         | 
| 98 | 
            +
             | 
| 99 | 
            +
            ## 🔐 Integration Types
         | 
| 100 | 
            +
            AgentR supports two primary integration types:
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            ### 1. API Key Integration
         | 
| 103 | 
            +
            For services that authenticate via API keys:
         | 
| 104 | 
            +
            ```python
         | 
| 105 | 
            +
            {
         | 
| 106 | 
            +
                "name": "service_name",
         | 
| 107 | 
            +
                "integration": {
         | 
| 108 | 
            +
                    "name": "service_api_key",
         | 
| 109 | 
            +
                    "type": "api_key",
         | 
| 110 | 
            +
                    "store": {
         | 
| 111 | 
            +
                        "type": "environment",  # or "memory"
         | 
| 112 | 
            +
                    }
         | 
| 113 | 
            +
                }
         | 
| 114 | 
            +
            }
         | 
| 115 | 
            +
            ```
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            ### 2. OAuth Integration (via AgentR)
         | 
| 118 | 
            +
            For services requiring OAuth flow:
         | 
| 119 | 
            +
            ```python
         | 
| 120 | 
            +
            {
         | 
| 121 | 
            +
                "name": "service_name",
         | 
| 122 | 
            +
                "integration": {
         | 
| 123 | 
            +
                    "name": "service_name",
         | 
| 124 | 
            +
                    "type": "agentr"
         | 
| 125 | 
            +
                }
         | 
| 126 | 
            +
            }
         | 
| 127 | 
            +
            ```
         | 
| 128 | 
            +
            When using OAuth integrations, users will be directed to authenticate with the service provider through a secure flow managed by AgentR.
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            ## 🤖 CLI Usage
         | 
| 131 | 
            +
            AgentR includes a command-line interface for common operations:
         | 
| 132 | 
            +
             | 
| 133 | 
            +
            ```bash
         | 
| 134 | 
            +
            # Get version information
         | 
| 135 | 
            +
            agentr version
         | 
| 136 | 
            +
             | 
| 137 | 
            +
            # Generate API client from OpenAPI schema
         | 
| 138 | 
            +
            agentr generate --schema path/to/openapi.yaml
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            # Run the test server
         | 
| 141 | 
            +
            agentr run
         | 
| 142 | 
            +
             | 
| 143 | 
            +
            # Install AgentR for specific applications
         | 
| 144 | 
            +
            agentr install claude
         | 
| 145 | 
            +
            ```
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            ## 📋 Requirements
         | 
| 148 | 
            +
             | 
| 149 | 
            +
            - Python 3.11+
         | 
| 150 | 
            +
            - Dependencies (automatically installed):
         | 
| 151 | 
            +
              - loguru >= 0.7.3
         | 
| 152 | 
            +
              - mcp >= 1.5.0
         | 
| 153 | 
            +
              - pyyaml >= 6.0.2
         | 
| 154 | 
            +
              - typer >= 0.15.2
         | 
| 155 | 
            +
             | 
| 156 | 
            +
             | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            agentr/__init__.py,sha256=oESTO4raGTykM5npHqhuwinRY-zxPtdmeOzXV-se_Bo,31
         | 
| 2 | 
            +
            agentr/application.py,sha256=jDcYk8DArOJuE-HEn6_aCUtMn_ckrFpJuoAv4qzyr6c,1607
         | 
| 3 | 
            +
            agentr/cli.py,sha256=UndJFUcJ7MCZzlhQB3W70j1oi1a-aYb1pZyKODNtdX8,2872
         | 
| 4 | 
            +
            agentr/exceptions.py,sha256=7VusZ_ltcYK3pRcew_Kc8rSllQoxi2RvmxdntJgufqM,275
         | 
| 5 | 
            +
            agentr/integration.py,sha256=Btd7VwKb1T94s9ZKApMDAEFv7tlK4oxHfBvIYRAmUe8,3657
         | 
| 6 | 
            +
            agentr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 7 | 
            +
            agentr/server.py,sha256=WB98K-BrSt77pp_wGTUnJa7Sjeyj_hFbbaB3hS9qnRA,4325
         | 
| 8 | 
            +
            agentr/store.py,sha256=IlCGsYjFIzVLsBnse5cuzS4egOn7osPr3zSUt3FwPvA,1655
         | 
| 9 | 
            +
            agentr/test.py,sha256=ijzm58aoCSJDAN-ObK2HludNMr2bbvPMURC7ah8wcu4,920
         | 
| 10 | 
            +
            agentr/applications/github/app.py,sha256=7ZOPDq95IaYza7IhNkB4zkeZmGDRxffhtRju6asUwLg,2005
         | 
| 11 | 
            +
            agentr/applications/google_calendar/app.py,sha256=9PFV_p0KbyuJslcaFnhDmqR6p3G7BR-3Ij5KIaPomTc,2914
         | 
| 12 | 
            +
            agentr/applications/google_mail/app.py,sha256=Pf_u0HE1Im7J9xe77RbknfaOmnspHRrKY40CpL270zU,2401
         | 
| 13 | 
            +
            agentr/applications/reddit/app.py,sha256=NLBPS0sAqUt5EVHeqcnAn4s6XD-KoapJjlLhSnsUgaY,871
         | 
| 14 | 
            +
            agentr/applications/resend/app.py,sha256=FWomwUKrrOHMptXO0P1wbe40JDyBvq_CC7Hrk0qcyWE,1471
         | 
| 15 | 
            +
            agentr/applications/tavily/app.py,sha256=WgnEqD0bROiDpliGEUSTww4vH5drRsHTBBGf8WRZacU,1862
         | 
| 16 | 
            +
            agentr/applications/zenquotes/app.py,sha256=WRK96H8cTWXRV-Z42QnOa1qfqzs6xmYTpxj1MJooYZM,627
         | 
| 17 | 
            +
            agentr/utils/bridge.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 18 | 
            +
            agentr/utils/openapi.py,sha256=S9MyxrxAs87-WTYgzfKVWhroxIB98_nBG1Ksac0x_pU,6463
         | 
| 19 | 
            +
            agentr-0.1.4.dist-info/METADATA,sha256=hMmkU1mQZbV2otCFm-Kirx7XS_Y4ca08NWRME5xm9y0,4173
         | 
| 20 | 
            +
            agentr-0.1.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
         | 
| 21 | 
            +
            agentr-0.1.4.dist-info/entry_points.txt,sha256=13fGFeVhgF6_8T-VFiIkNxYO7gDQaUwwTcUNWdvaLQg,42
         | 
| 22 | 
            +
            agentr-0.1.4.dist-info/RECORD,,
         | 
    
        agentr-0.1.3.dist-info/METADATA
    DELETED
    
    | @@ -1,10 +0,0 @@ | |
| 1 | 
            -
            Metadata-Version: 2.4
         | 
| 2 | 
            -
            Name: agentr
         | 
| 3 | 
            -
            Version: 0.1.3
         | 
| 4 | 
            -
            Summary: Add your description here
         | 
| 5 | 
            -
            Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
         | 
| 6 | 
            -
            Requires-Python: >=3.11
         | 
| 7 | 
            -
            Requires-Dist: loguru>=0.7.3
         | 
| 8 | 
            -
            Requires-Dist: mcp>=1.5.0
         | 
| 9 | 
            -
            Requires-Dist: pyyaml>=6.0.2
         | 
| 10 | 
            -
            Requires-Dist: typer>=0.15.2
         | 
    
        agentr-0.1.3.dist-info/RECORD
    DELETED
    
    | @@ -1,21 +0,0 @@ | |
| 1 | 
            -
            agentr/__init__.py,sha256=LOWhgQayrQV7f5ro4rlBJ_6WevhbWIbjAOHnqP7b_-4,30
         | 
| 2 | 
            -
            agentr/application.py,sha256=2K7jL5QUDwlD_zRS7adN_R3_yPt-EJBYpAmr1abDew8,1551
         | 
| 3 | 
            -
            agentr/cli.py,sha256=KcmYrnzoVzkh4SWB6UDjxGJboQbMcphj1juNbfqrIAE,1676
         | 
| 4 | 
            -
            agentr/integration.py,sha256=jRwpp_bUXJWl8OkZsnRDqoScoRSxCMDBMrDMfRBhgN4,3298
         | 
| 5 | 
            -
            agentr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 6 | 
            -
            agentr/server.py,sha256=24cD8e3ks8ckftPMphI7K3SfGs8LZZyXpfiKU2daY-Q,4220
         | 
| 7 | 
            -
            agentr/store.py,sha256=fB3uAaobnWf2ILcDBmg3ToDaqAIPYlLtmHBdpmkcGcI,1585
         | 
| 8 | 
            -
            agentr/test.py,sha256=A0t1fdI9N89eF9xm903fKtvTzibnrHeMKkPwZnSBEc4,852
         | 
| 9 | 
            -
            agentr/applications/github/app.py,sha256=_PW_xzkCzNB468lEOvFzdQk0m7Ol6y_PQ5OqCkVkDVE,1811
         | 
| 10 | 
            -
            agentr/applications/google_calendar/app.py,sha256=WW-4MTqPl-NU2w5DKKyEvfTho4d6tS7t52jDRyq-tv0,2841
         | 
| 11 | 
            -
            agentr/applications/google_mail/app.py,sha256=SqzWyYW0xF_fdZC8kf_8FZfQK6OOddI-EVpdgYAengg,2334
         | 
| 12 | 
            -
            agentr/applications/reddit/app.py,sha256=iNkSRVGScj7Mae3e8N-Mkov_hvZrvH5NynbpO8mKToQ,842
         | 
| 13 | 
            -
            agentr/applications/resend/app.py,sha256=ihRzP65bwoNIq3EzBqIghxgLZRxvy-LbHy-rER20ODo,1428
         | 
| 14 | 
            -
            agentr/applications/tavily/app.py,sha256=D4FOhm2yxNbuTVHTo3T8ZsuE5AgwK874YutfYx2Njcw,1805
         | 
| 15 | 
            -
            agentr/applications/zenquotes/app.py,sha256=4LjYeWdERI8ZMzkajOsDgy9IRTA9plUKem-rW4M03sA,607
         | 
| 16 | 
            -
            agentr/utils/bridge.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 17 | 
            -
            agentr/utils/openapi.py,sha256=yjiPYs-_JsYQ7T3aPh7oimHUCf8pMblIR8IPCaAeNCg,6279
         | 
| 18 | 
            -
            agentr-0.1.3.dist-info/METADATA,sha256=YWWFhc2Z9sG48D4zr7lIDJ39JO_pK13RZ5mQO1jiWEY,273
         | 
| 19 | 
            -
            agentr-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
         | 
| 20 | 
            -
            agentr-0.1.3.dist-info/entry_points.txt,sha256=13fGFeVhgF6_8T-VFiIkNxYO7gDQaUwwTcUNWdvaLQg,42
         | 
| 21 | 
            -
            agentr-0.1.3.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         |