math-ai-agent 0.0.1__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.
- math_ai_agent/__init__.py +39 -0
- math_ai_agent/app.py +109 -0
- math_ai_agent/config/__init__.py +39 -0
- math_ai_agent/config/config.py +148 -0
- math_ai_agent/config/config.yaml +143 -0
- math_ai_agent/llm/__init__.py +47 -0
- math_ai_agent/llm/agent.py +369 -0
- math_ai_agent/llm/client.py +230 -0
- math_ai_agent/mcp/__init__.py +39 -0
- math_ai_agent/mcp/calc_client.py +291 -0
- math_ai_agent/prompt.py +47 -0
- math_ai_agent/static/index.html +158 -0
- math_ai_agent-0.0.1.dist-info/METADATA +373 -0
- math_ai_agent-0.0.1.dist-info/RECORD +16 -0
- math_ai_agent-0.0.1.dist-info/WHEEL +4 -0
- math_ai_agent-0.0.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# General Disclaimer
|
|
2
|
+
#
|
|
3
|
+
# **AI Generated Content**
|
|
4
|
+
#
|
|
5
|
+
# This project's source code and documentation were generated predominantly
|
|
6
|
+
# by an Artificial Intelligence Large Language Model (AI LLM). The project
|
|
7
|
+
# lead, [Rubens Gomes](https://rubensgomes.com), provided initial prompts,
|
|
8
|
+
# reviewed, and made refinements to the generated output. While human review and
|
|
9
|
+
# refinement have occurred, users should be aware that the output may contain
|
|
10
|
+
# inaccuracies, errors, or security vulnerabilities
|
|
11
|
+
#
|
|
12
|
+
# **Third-Party Content Notice**
|
|
13
|
+
#
|
|
14
|
+
# This software may include components or snippets derived from third-party
|
|
15
|
+
# sources. The software's users and distributors are responsible for ensuring
|
|
16
|
+
# compliance with any underlying licenses applicable to such components.
|
|
17
|
+
#
|
|
18
|
+
# **Copyright Status Statement**
|
|
19
|
+
#
|
|
20
|
+
# Copyright protection, if any, is limited to the original
|
|
21
|
+
# human contributions and modifications made to this project.
|
|
22
|
+
# The AI-generated portions of the code and
|
|
23
|
+
# documentation are not subject to copyright and are considered to be in the
|
|
24
|
+
# public domain.
|
|
25
|
+
#
|
|
26
|
+
# **Limitation of liability**
|
|
27
|
+
#
|
|
28
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
29
|
+
# DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
|
|
30
|
+
# OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
31
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
|
32
|
+
#
|
|
33
|
+
# **No-Warranty Disclaimer**
|
|
34
|
+
#
|
|
35
|
+
# THIS SOFTWARE IS PROVIDED 'AS IS,' WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
36
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
# FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
38
|
+
|
|
39
|
+
"""math_ai_agent — Math AI Agent package."""
|
math_ai_agent/app.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# General Disclaimer
|
|
2
|
+
#
|
|
3
|
+
# **AI Generated Content**
|
|
4
|
+
#
|
|
5
|
+
# This project's source code and documentation were generated predominantly
|
|
6
|
+
# by an Artificial Intelligence Large Language Model (AI LLM). The project
|
|
7
|
+
# lead, [Rubens Gomes](https://rubensgomes.com), provided initial prompts,
|
|
8
|
+
# reviewed, and made refinements to the generated output. While human review and
|
|
9
|
+
# refinement have occurred, users should be aware that the output may contain
|
|
10
|
+
# inaccuracies, errors, or security vulnerabilities
|
|
11
|
+
#
|
|
12
|
+
# **Third-Party Content Notice**
|
|
13
|
+
#
|
|
14
|
+
# This software may include components or snippets derived from third-party
|
|
15
|
+
# sources. The software's users and distributors are responsible for ensuring
|
|
16
|
+
# compliance with any underlying licenses applicable to such components.
|
|
17
|
+
#
|
|
18
|
+
# **Copyright Status Statement**
|
|
19
|
+
#
|
|
20
|
+
# Copyright protection, if any, is limited to the original
|
|
21
|
+
# human contributions and modifications made to this project.
|
|
22
|
+
# The AI-generated portions of the code and
|
|
23
|
+
# documentation are not subject to copyright and are considered to be in the
|
|
24
|
+
# public domain.
|
|
25
|
+
#
|
|
26
|
+
# **Limitation of liability**
|
|
27
|
+
#
|
|
28
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
29
|
+
# DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
|
|
30
|
+
# OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
31
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
|
32
|
+
#
|
|
33
|
+
# **No-Warranty Disclaimer**
|
|
34
|
+
#
|
|
35
|
+
# THIS SOFTWARE IS PROVIDED 'AS IS,' WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
36
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
# FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
38
|
+
|
|
39
|
+
"""The FastAPI web server app.
|
|
40
|
+
|
|
41
|
+
Launches a FastAPI web server with the following endpoints:
|
|
42
|
+
- `GET /` returns the index.html page.
|
|
43
|
+
- `POST /prompt/` submits user prompt and returns AI response.
|
|
44
|
+
|
|
45
|
+
From the project root folder run::
|
|
46
|
+
|
|
47
|
+
poetry run uvicorn math_ai_agent.app:app --reload
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
import json
|
|
51
|
+
import logging
|
|
52
|
+
from pathlib import Path
|
|
53
|
+
|
|
54
|
+
from fastapi import FastAPI
|
|
55
|
+
from fastapi.responses import HTMLResponse
|
|
56
|
+
from fastapi.staticfiles import StaticFiles
|
|
57
|
+
|
|
58
|
+
from math_ai_agent.config.config import configure_logging
|
|
59
|
+
from math_ai_agent.llm import agent_loop
|
|
60
|
+
from math_ai_agent.prompt import Prompt
|
|
61
|
+
|
|
62
|
+
configure_logging()
|
|
63
|
+
logger = logging.getLogger(__name__)
|
|
64
|
+
|
|
65
|
+
# folder to HTML file
|
|
66
|
+
_STATIC_DIR = Path(__file__).parent / "static"
|
|
67
|
+
|
|
68
|
+
# -------------------------------------------------
|
|
69
|
+
# Create the FastAPI app instance
|
|
70
|
+
# -------------------------------------------------
|
|
71
|
+
app = FastAPI()
|
|
72
|
+
app.mount("/static", StaticFiles(directory=_STATIC_DIR), name="static")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# -------------------------------------------------
|
|
76
|
+
# Routes
|
|
77
|
+
# -------------------------------------------------
|
|
78
|
+
@app.get("/", response_class=HTMLResponse)
|
|
79
|
+
async def root() -> str:
|
|
80
|
+
"""Serve the main HTML page.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The HTML content of the index page.
|
|
84
|
+
"""
|
|
85
|
+
logger.debug("Serving root HTML page: %s%s", _STATIC_DIR, "/index.html")
|
|
86
|
+
return (_STATIC_DIR / "index.html").read_text()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@app.post("/prompt/")
|
|
90
|
+
async def prompt(payload: Prompt) -> dict[str, str]:
|
|
91
|
+
"""Accept a prompt text from the user and return an answer.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
payload: The validated question from the request body.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
A dict containing the `answer` key with the response.
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
RuntimeError: If the agent loop encounters a token limit
|
|
101
|
+
or content filter error.
|
|
102
|
+
ValueError: If the LLM returns an unknown finish reason.
|
|
103
|
+
"""
|
|
104
|
+
logger.debug("Received prompt: %s", payload.text)
|
|
105
|
+
prompt_text = payload.text.strip()
|
|
106
|
+
logger.debug("Calling LLM with user prompt: %s", prompt_text)
|
|
107
|
+
output = await agent_loop(prompt_text)
|
|
108
|
+
logger.debug("Output:\n%s", json.dumps(output, indent=2))
|
|
109
|
+
return {"answer": output}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# General Disclaimer
|
|
2
|
+
#
|
|
3
|
+
# **AI Generated Content**
|
|
4
|
+
#
|
|
5
|
+
# This project's source code and documentation were generated predominantly
|
|
6
|
+
# by an Artificial Intelligence Large Language Model (AI LLM). The project
|
|
7
|
+
# lead, [Rubens Gomes](https://rubensgomes.com), provided initial prompts,
|
|
8
|
+
# reviewed, and made refinements to the generated output. While human review and
|
|
9
|
+
# refinement have occurred, users should be aware that the output may contain
|
|
10
|
+
# inaccuracies, errors, or security vulnerabilities
|
|
11
|
+
#
|
|
12
|
+
# **Third-Party Content Notice**
|
|
13
|
+
#
|
|
14
|
+
# This software may include components or snippets derived from third-party
|
|
15
|
+
# sources. The software's users and distributors are responsible for ensuring
|
|
16
|
+
# compliance with any underlying licenses applicable to such components.
|
|
17
|
+
#
|
|
18
|
+
# **Copyright Status Statement**
|
|
19
|
+
#
|
|
20
|
+
# Copyright protection, if any, is limited to the original
|
|
21
|
+
# human contributions and modifications made to this project.
|
|
22
|
+
# The AI-generated portions of the code and
|
|
23
|
+
# documentation are not subject to copyright and are considered to be in the
|
|
24
|
+
# public domain.
|
|
25
|
+
#
|
|
26
|
+
# **Limitation of liability**
|
|
27
|
+
#
|
|
28
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
29
|
+
# DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
|
|
30
|
+
# OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
31
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
|
32
|
+
#
|
|
33
|
+
# **No-Warranty Disclaimer**
|
|
34
|
+
#
|
|
35
|
+
# THIS SOFTWARE IS PROVIDED 'AS IS,' WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
36
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
# FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
38
|
+
|
|
39
|
+
"""config — configuration sub-package for math_ai_agent."""
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# General Disclaimer
|
|
2
|
+
#
|
|
3
|
+
# **AI Generated Content**
|
|
4
|
+
#
|
|
5
|
+
# This project's source code and documentation were generated predominantly
|
|
6
|
+
# by an Artificial Intelligence Large Language Model (AI LLM). The project
|
|
7
|
+
# lead, [Rubens Gomes](https://rubensgomes.com), provided initial prompts,
|
|
8
|
+
# reviewed, and made refinements to the generated output. While human review and
|
|
9
|
+
# refinement have occurred, users should be aware that the output may contain
|
|
10
|
+
# inaccuracies, errors, or security vulnerabilities
|
|
11
|
+
#
|
|
12
|
+
# **Third-Party Content Notice**
|
|
13
|
+
#
|
|
14
|
+
# This software may include components or snippets derived from third-party
|
|
15
|
+
# sources. The software's users and distributors are responsible for ensuring
|
|
16
|
+
# compliance with any underlying licenses applicable to such components.
|
|
17
|
+
#
|
|
18
|
+
# **Copyright Status Statement**
|
|
19
|
+
#
|
|
20
|
+
# Copyright protection, if any, is limited to the original
|
|
21
|
+
# human contributions and modifications made to this project.
|
|
22
|
+
# The AI-generated portions of the code and
|
|
23
|
+
# documentation are not subject to copyright and are considered to be in the
|
|
24
|
+
# public domain.
|
|
25
|
+
#
|
|
26
|
+
# **Limitation of liability**
|
|
27
|
+
#
|
|
28
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
29
|
+
# DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
|
|
30
|
+
# OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
31
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
|
32
|
+
#
|
|
33
|
+
# **No-Warranty Disclaimer**
|
|
34
|
+
#
|
|
35
|
+
# THIS SOFTWARE IS PROVIDED 'AS IS,' WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
36
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
# FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
38
|
+
|
|
39
|
+
"""Configuration helpers — loads config.yaml and configures logging."""
|
|
40
|
+
|
|
41
|
+
import functools
|
|
42
|
+
import logging
|
|
43
|
+
import logging.config
|
|
44
|
+
import os
|
|
45
|
+
from importlib.resources import files
|
|
46
|
+
from pathlib import Path
|
|
47
|
+
from typing import Any, Literal
|
|
48
|
+
|
|
49
|
+
import yaml
|
|
50
|
+
from pydantic import BaseModel
|
|
51
|
+
|
|
52
|
+
logger = logging.getLogger(__name__)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class LLMConfig(BaseModel):
|
|
56
|
+
"""The ``llm`` section of config.yaml."""
|
|
57
|
+
|
|
58
|
+
api_style: Literal["chat", "responses"] = "chat"
|
|
59
|
+
model_base_url: str
|
|
60
|
+
model: str
|
|
61
|
+
api_key_env: str
|
|
62
|
+
system_instructions: str
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class CalculatorMCPConfig(BaseModel):
|
|
66
|
+
"""The ``server.calculator_mcp`` section of config.yaml."""
|
|
67
|
+
|
|
68
|
+
url: str
|
|
69
|
+
is_oauth: bool = False
|
|
70
|
+
token_dir: str
|
|
71
|
+
callback_port: int
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ServerConfig(BaseModel):
|
|
75
|
+
"""The ``server`` section of config.yaml."""
|
|
76
|
+
|
|
77
|
+
calculator_mcp: CalculatorMCPConfig
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class AppConfig(BaseModel):
|
|
81
|
+
"""The full config.yaml; ``logging`` is a ``dictConfig`` mapping."""
|
|
82
|
+
|
|
83
|
+
llm: LLMConfig
|
|
84
|
+
server: ServerConfig
|
|
85
|
+
logging: dict[str, Any]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _resolve_config_path() -> Path:
|
|
89
|
+
"""Return the config.yaml path.
|
|
90
|
+
|
|
91
|
+
Resolution order:
|
|
92
|
+
|
|
93
|
+
1. The ``MATHAIAGENT_CONFIG`` environment variable, when set.
|
|
94
|
+
2. The ``config.yaml`` bundled inside the
|
|
95
|
+
``math_ai_agent.config`` package.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
The resolved path to config.yaml.
|
|
99
|
+
"""
|
|
100
|
+
env_path = os.environ.get("MATHAIAGENT_CONFIG")
|
|
101
|
+
if env_path:
|
|
102
|
+
return Path(env_path)
|
|
103
|
+
return Path(str(files("math_ai_agent.config").joinpath("config.yaml")))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def load_config(path: Path) -> AppConfig:
|
|
107
|
+
"""Parse and validate the config file at ``path``.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
pydantic.ValidationError: If the file does not match the models.
|
|
111
|
+
"""
|
|
112
|
+
with open(path, encoding="utf-8") as f:
|
|
113
|
+
return AppConfig.model_validate(yaml.safe_load(f))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@functools.cache
|
|
117
|
+
def get_config() -> AppConfig:
|
|
118
|
+
"""Return the application config, loaded once on first call."""
|
|
119
|
+
return load_config(_resolve_config_path())
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def configure_logging() -> None:
|
|
123
|
+
"""Apply the logging configuration from config.yaml."""
|
|
124
|
+
logging.config.dictConfig(get_config().logging)
|
|
125
|
+
logger.debug("Loaded config from %s", _resolve_config_path())
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def get_api_key() -> str:
|
|
129
|
+
"""Return the LLM API key from the environment.
|
|
130
|
+
|
|
131
|
+
The config.yaml ``llm.api_key_env`` setting names the environment
|
|
132
|
+
variable holding the key; the key value itself is never stored in
|
|
133
|
+
config.yaml. Only the variable name is logged, never the key.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
The API key read from the configured environment variable.
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
RuntimeError: If the environment variable is not set or empty.
|
|
140
|
+
"""
|
|
141
|
+
env_name = get_config().llm.api_key_env
|
|
142
|
+
logger.info("LLM API key environment variable: %s", env_name)
|
|
143
|
+
api_key = os.environ.get(env_name)
|
|
144
|
+
if not api_key:
|
|
145
|
+
error = f"{env_name} environment variable is not set."
|
|
146
|
+
logger.error(error)
|
|
147
|
+
raise RuntimeError(error)
|
|
148
|
+
return api_key
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# LLM Configuration
|
|
3
|
+
# =============================================================================
|
|
4
|
+
llm:
|
|
5
|
+
# Which OpenAI API the LLM client uses:
|
|
6
|
+
# "responses" -> POST /v1/responses (primary OpenAI API)
|
|
7
|
+
# "chat" -> POST /v1/chat/completions (legacy, still supported)
|
|
8
|
+
# Both work against NVIDIA nemotron models
|
|
9
|
+
api_style: "responses"
|
|
10
|
+
# Base NVIDIA LLM models URL
|
|
11
|
+
model_base_url: "https://integrate.api.nvidia.com/v1"
|
|
12
|
+
# Nemotron frontier NVIDIA models for agentic workflows, coding and tool use
|
|
13
|
+
# See list of NVIDIA models: https://integrate.api.nvidia.com/v1/models
|
|
14
|
+
model: "nvidia/nemotron-3-super-120b-a12b"
|
|
15
|
+
# Name of the environment variable holding the API key.
|
|
16
|
+
# Get a key from https://build.nvidia.com (keys start with "nvapi-").
|
|
17
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
18
|
+
# System prompt sent to the **stateless** LLM on every request.
|
|
19
|
+
system_instructions: >-
|
|
20
|
+
You are a careful math assistant tutor helping solve math problems.
|
|
21
|
+
Always write a short plan first. Do NOT do arithmetic in your head.
|
|
22
|
+
For every math operation, request a tool call to the calculator.
|
|
23
|
+
After tool results, continue. Provide final answer with explanation.
|
|
24
|
+
Respond in plain text only. Do NOT use LaTeX, Markdown, or any other
|
|
25
|
+
special formatting: no backslashes, no asterisks, no dollar-sign or
|
|
26
|
+
parenthesis math delimiters. Write math inline, like 4 x 3 = 12.
|
|
27
|
+
Your answer is shown in a plain text box that cannot render
|
|
28
|
+
formatting.
|
|
29
|
+
|
|
30
|
+
# OpenRouter alternative. Its free tier allows only 50 requests per
|
|
31
|
+
# day, after which requests fail with 429 free-models-per-day. The
|
|
32
|
+
# ":free" suffix is OpenRouter slug syntax and is not a valid model
|
|
33
|
+
# id on any other provider.
|
|
34
|
+
# model_base_url: "https://openrouter.ai/api/v1"
|
|
35
|
+
# model: "nvidia/nemotron-3-super-120b-a12b:free"
|
|
36
|
+
# api_key_env: "OPENROUTER_API_KEY"
|
|
37
|
+
# Local Ollama alternative (see OLLAMA.md):
|
|
38
|
+
# model_base_url: "http://localhost:11434/v1"
|
|
39
|
+
# model: "phi"
|
|
40
|
+
|
|
41
|
+
# =============================================================================
|
|
42
|
+
# Calculator MCP Server Configuration
|
|
43
|
+
# =============================================================================
|
|
44
|
+
server:
|
|
45
|
+
calculator_mcp:
|
|
46
|
+
# URL of the Calculator MCP Server End-Point
|
|
47
|
+
# url: "http://127.0.0.1:8080/mcp"
|
|
48
|
+
# Hosted, deployed and running for free at Prefect
|
|
49
|
+
# https://www.prefect.io/horizon
|
|
50
|
+
url: "https://rubens-calculator-mcp.fastmcp.app/mcp"
|
|
51
|
+
# is_oauth: false
|
|
52
|
+
# Prefect requires OAuth authentication. Currently only Rubens is able
|
|
53
|
+
# to authorize using his personal GitHub account.
|
|
54
|
+
is_oauth: true
|
|
55
|
+
# location to store OAuth token
|
|
56
|
+
token_dir: "~/.mathaiagent"
|
|
57
|
+
# local port temporarily used by the OAuth callback server during
|
|
58
|
+
# OAuth handshaking.
|
|
59
|
+
callback_port: 10000
|
|
60
|
+
|
|
61
|
+
# =============================================================================
|
|
62
|
+
# Logging Configuration
|
|
63
|
+
# =============================================================================
|
|
64
|
+
logging:
|
|
65
|
+
version: 1
|
|
66
|
+
disable_existing_loggers: false
|
|
67
|
+
formatters:
|
|
68
|
+
# Colors level name and message; plain if stderr is not a TTY or NO_COLOR
|
|
69
|
+
# set environment variable NO_COLOR=true for plain text with no color.
|
|
70
|
+
standard:
|
|
71
|
+
(): colorlog.ColoredFormatter
|
|
72
|
+
fmt: "%(asctime)s %(log_color)s[%(levelname)s]%(reset)s %(fg_147)s%(name)s %(filename)s:%(lineno)d%(reset)s: %(log_color)s%(message)s%(reset)s"
|
|
73
|
+
datefmt: "%H:%M:%S"
|
|
74
|
+
log_colors:
|
|
75
|
+
DEBUG: cyan
|
|
76
|
+
INFO: light_green
|
|
77
|
+
WARNING: yellow
|
|
78
|
+
ERROR: red
|
|
79
|
+
CRITICAL: bold_red
|
|
80
|
+
stream: ext://sys.stderr
|
|
81
|
+
handlers:
|
|
82
|
+
console:
|
|
83
|
+
class: logging.StreamHandler
|
|
84
|
+
formatter: standard
|
|
85
|
+
stream: ext://sys.stderr
|
|
86
|
+
loggers:
|
|
87
|
+
math_ai_agent:
|
|
88
|
+
level: DEBUG
|
|
89
|
+
handlers:
|
|
90
|
+
- console
|
|
91
|
+
propagate: false
|
|
92
|
+
# MCP protocol tracing — set to DEBUG to see full JSON-RPC messages
|
|
93
|
+
mcp.client.streamable_http:
|
|
94
|
+
level: INFO
|
|
95
|
+
handlers:
|
|
96
|
+
- console
|
|
97
|
+
propagate: false
|
|
98
|
+
# HTTP request/response summaries — set to DEBUG for detail
|
|
99
|
+
httpx:
|
|
100
|
+
level: INFO
|
|
101
|
+
handlers:
|
|
102
|
+
- console
|
|
103
|
+
propagate: false
|
|
104
|
+
# OpenAI SDK logging — set to DEBUG for request/response detail
|
|
105
|
+
openai:
|
|
106
|
+
level: INFO
|
|
107
|
+
handlers:
|
|
108
|
+
- console
|
|
109
|
+
propagate: false
|
|
110
|
+
# HTTP wire-level tracing (headers, TCP) — set to DEBUG for detail
|
|
111
|
+
httpcore:
|
|
112
|
+
level: INFO
|
|
113
|
+
handlers:
|
|
114
|
+
- console
|
|
115
|
+
propagate: false
|
|
116
|
+
# Server: startup, shutdown, and errors
|
|
117
|
+
uvicorn:
|
|
118
|
+
level: INFO
|
|
119
|
+
handlers:
|
|
120
|
+
- console
|
|
121
|
+
propagate: false
|
|
122
|
+
# Server: HTTP request lines (method, path, status)
|
|
123
|
+
uvicorn.access:
|
|
124
|
+
level: INFO
|
|
125
|
+
handlers:
|
|
126
|
+
- console
|
|
127
|
+
propagate: false
|
|
128
|
+
# Integration tests (via pytest)
|
|
129
|
+
tests:
|
|
130
|
+
level: DEBUG
|
|
131
|
+
handlers:
|
|
132
|
+
- console
|
|
133
|
+
propagate: false
|
|
134
|
+
# Integration tests (run standalone)
|
|
135
|
+
__main__:
|
|
136
|
+
level: DEBUG
|
|
137
|
+
handlers:
|
|
138
|
+
- console
|
|
139
|
+
propagate: false
|
|
140
|
+
root:
|
|
141
|
+
level: WARNING
|
|
142
|
+
handlers:
|
|
143
|
+
- console
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# General Disclaimer
|
|
2
|
+
#
|
|
3
|
+
# **AI Generated Content**
|
|
4
|
+
#
|
|
5
|
+
# This project's source code and documentation were generated predominantly
|
|
6
|
+
# by an Artificial Intelligence Large Language Model (AI LLM). The project
|
|
7
|
+
# lead, [Rubens Gomes](https://rubensgomes.com), provided initial prompts,
|
|
8
|
+
# reviewed, and made refinements to the generated output. While human review and
|
|
9
|
+
# refinement have occurred, users should be aware that the output may contain
|
|
10
|
+
# inaccuracies, errors, or security vulnerabilities
|
|
11
|
+
#
|
|
12
|
+
# **Third-Party Content Notice**
|
|
13
|
+
#
|
|
14
|
+
# This software may include components or snippets derived from third-party
|
|
15
|
+
# sources. The software's users and distributors are responsible for ensuring
|
|
16
|
+
# compliance with any underlying licenses applicable to such components.
|
|
17
|
+
#
|
|
18
|
+
# **Copyright Status Statement**
|
|
19
|
+
#
|
|
20
|
+
# Copyright protection, if any, is limited to the original
|
|
21
|
+
# human contributions and modifications made to this project.
|
|
22
|
+
# The AI-generated portions of the code and
|
|
23
|
+
# documentation are not subject to copyright and are considered to be in the
|
|
24
|
+
# public domain.
|
|
25
|
+
#
|
|
26
|
+
# **Limitation of liability**
|
|
27
|
+
#
|
|
28
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
29
|
+
# DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
|
|
30
|
+
# OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
31
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
|
32
|
+
#
|
|
33
|
+
# **No-Warranty Disclaimer**
|
|
34
|
+
#
|
|
35
|
+
# THIS SOFTWARE IS PROVIDED 'AS IS,' WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
36
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
# FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
38
|
+
|
|
39
|
+
"""llm — LLM sub-package for math_ai_agent.
|
|
40
|
+
|
|
41
|
+
Re-exports ``agent_loop`` so callers can use
|
|
42
|
+
``from math_ai_agent.llm import agent_loop``.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from math_ai_agent.llm.agent import agent_loop
|
|
46
|
+
|
|
47
|
+
__all__ = ["agent_loop"]
|