-
Couldn't load subscription status.
- Fork 4
Derive all equations in parallel new MCP tools: Analyser + Executer #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… for API requests and improve mermaid text formatting
- Updated server initialization to include new feedback prompts for the derive_all_equations workflow. - Enhanced documentation within the code to clarify the workflow and user instructions.
…s normally handled by the client model.
Walkthrough
Estimated code review effort
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
axiomatic_mcp/servers/equations/server.py (1)
71-94: Critical: Instructions reference undefined tool.The instructions reference
derive_all_equations_modifyin multiple places (lines 80, 89), but this tool is not defined in the codebase.• Line 80: "If user wants changes: call derive_all_equations_modify"
• Line 89: Tool name included in feedback prompt
• PR objectives mention only analyze and execute tools—no modify toolImpact: LLM will attempt to call a non-existent tool, causing workflow failures.
Resolution: Remove all references to the modify tool and update workflow instructions to handle user-requested changes differently (e.g., "manually adjust the eligible_equations list").
Apply this diff:
CRITICAL: For the derive_all_equations workflow, you MUST follow this exact pattern: 1. Call derive_all_equations_analyze 2. Show results to user and ASK: "Are you satisfied with this categorization, or would you like to make changes?" 3. Based on user response: - - If user wants changes: call derive_all_equations_modify → show results → ASK AGAIN (repeat as needed) + - If user wants changes: help them manually adjust the eligible_equations list → show results → ASK AGAIN (repeat as needed) - If user approves: IMMEDIATELY call derive_all_equations_execute (don't ask again, just do it) 4. NEVER skip asking the user for approval after analyze/modify 5. ALWAYS execute automatically once user approves (this is the final step, no more modifications) -The modify tool is OPTIONAL and should only be called if user explicitly wants changes. Otherwise proceed directly to execute after user approval. +Manual modifications are OPTIONAL and should only be done if user explicitly wants changes. Otherwise proceed directly to execute after user approval. """ + get_feedback_prompt( - "find_functional_form, check_equation, generate_derivation_graph, " - "derive_all_equations_analyze, derive_all_equations_modify, derive_all_equations_execute" + "find_functional_form, check_equation, generate_derivation_graph, " + "derive_all_equations_analyze, derive_all_equations_execute" ),
🧹 Nitpick comments (2)
axiomatic_mcp/servers/equations/server.py (2)
403-403: Generic file naming reduces discoverability.Files are named
equation_1.py,equation_2.py, etc., with no indication of their content. Users must open each file to identify which equation it contains.• Consider deriving filenames from equation content (sanitized LaTeX or first few symbols)
• Or include equation metadata in filename (e.g.,equation_1_energy_momentum.py)Example implementation using equation snippet:
# After line 397 import re def sanitize_for_filename(equation: str, max_length: int = 30) -> str: """Convert equation to safe filename fragment.""" # Remove LaTeX commands and special chars, keep alphanumerics safe = re.sub(r'[^\w\s-]', '', equation) safe = re.sub(r'[-\s]+', '_', safe.strip()) return safe[:max_length].lower() # Then at line 403: equation_snippet = sanitize_for_filename(equation) file_path = output_dir / f"equation_{i}_{equation_snippet}.py"
370-370: Time estimation formula is rough—consider documenting rationale.Line 370:
estimated_minutes = max(2, (num_equations // 10) * 3)This assumes ~3 minutes per 10 equations, which may not reflect actual API performance. If users see significant deviations, they may lose trust in progress estimates.
• Document the rationale behind the formula
• Or remove specific time estimates and use qualitative descriptions ("a few minutes", "several minutes")
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (1)
axiomatic_mcp/servers/equations/server.py(4 hunks)
🔇 Additional comments (3)
axiomatic_mcp/servers/equations/server.py (3)
44-69: LGTM! Helper function follows established patterns.The implementation correctly mirrors the
_get_document_contentpattern and handles both file paths and raw code strings appropriately.Note: The 500-character heuristic for path detection is reasonable but arbitrary—acceptable for practical use cases where real code would exceed this length.
271-324: LGTM! Clean analysis implementation.The tool correctly:
• Calls the API endpoint for equation categorization
• Formats results in a clear, user-friendly structure
• Returns comprehensive analysis with rationale per equation
250-255: No API format tests found—confirm contract
- No references to
mermaid_textor/equations/compose/derivation-graphin tests/docs- Verify the endpoint always returns raw Mermaid (no fences) or consistently includes code fences
- Then enforce a single convention (strip before wrapping or assume already fenced)
| doc_content = await _get_document_content(document) | ||
|
|
||
| # Extract just the equation strings from the dict objects | ||
| equations_to_derive = [eq.get("equation") for eq in eligible_equations] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for eligible_equations structure.
Line 364 extracts equation keys without validating that each dict contains this key. If the structure is malformed, this produces a list of None values that fail silently or cause downstream errors.
• Add validation before extraction
• Provide clear error message if structure is invalid
Apply this diff:
# Extract just the equation strings from the dict objects
+ # Validate structure first
+ for i, eq in enumerate(eligible_equations):
+ if not isinstance(eq, dict) or 'equation' not in eq:
+ raise ToolError(f"Invalid equation structure at index {i}: expected dict with 'equation' key")
+
equations_to_derive = [eq.get("equation") for eq in eligible_equations]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| equations_to_derive = [eq.get("equation") for eq in eligible_equations] | |
| # Extract just the equation strings from the dict objects | |
| # Validate structure first | |
| for i, eq in enumerate(eligible_equations): | |
| if not isinstance(eq, dict) or 'equation' not in eq: | |
| raise ToolError(f"Invalid equation structure at index {i}: expected dict with 'equation' key") | |
| equations_to_derive = [eq.get("equation") for eq in eligible_equations] |
🤖 Prompt for AI Agents
In axiomatic_mcp/servers/equations/server.py around line 364, the code blindly
builds equations_to_derive = [eq.get("equation") for eq in eligible_equations]
which can produce None values if eligible_equations is malformed; validate that
eligible_equations is an iterable of dict-like objects and that each item
contains a non-empty "equation" key before extraction, e.g. check type and
presence, collect any invalid entries and either raise a clear ValueError (or
return an HTTP 400 with a descriptive message) listing the offending
indices/items, or filter them out and log a warning so downstream code never
receives None values. Ensure the validation happens immediately before line 364
and that the error message names the field ("equation") and the problematic
items/indices.
| execute_response = AxiomaticAPIClient().post( | ||
| "/equations/derive-all/execute", | ||
| data={"markdown": doc_content, "eligible_equations": equations_to_derive}, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Consider timeout handling for long-running operations.
The API call blocks for 2–10 minutes (per line 332) with no timeout configuration. If the backend hangs or takes longer than expected, the client waits indefinitely.
• Add explicit timeout parameter to the API call
• Handle timeout exceptions gracefully
Apply this diff:
# Call synchronous execute endpoint (will block until complete)
execute_response = AxiomaticAPIClient().post(
"/equations/derive-all/execute",
data={"markdown": doc_content, "eligible_equations": equations_to_derive},
+ timeout=600, # 10 minutes max
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| execute_response = AxiomaticAPIClient().post( | |
| "/equations/derive-all/execute", | |
| data={"markdown": doc_content, "eligible_equations": equations_to_derive}, | |
| ) | |
| # Call synchronous execute endpoint (will block until complete) | |
| execute_response = AxiomaticAPIClient().post( | |
| "/equations/derive-all/execute", | |
| data={"markdown": doc_content, "eligible_equations": equations_to_derive}, | |
| timeout=600, # 10 minutes max | |
| ) |
🤖 Prompt for AI Agents
In axiomatic_mcp/servers/equations/server.py around lines 378 to 381, the
AxiomaticAPIClient().post call that triggers a long-running backend derive
operation must include an explicit timeout (e.g., timeout=300 or other suitable
seconds) and be wrapped in a try/except to handle timeouts; add the timeout
parameter to the post call, catch the client's timeout exception
(requests.exceptions.Timeout or the HTTP client’s TimeoutException depending on
AxiomaticAPIClient implementation), log the timeout with context, and
return/raise a clear error response to avoid hanging the server.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks to me that this applies changes on top of #38. can you please address the review comments there? or change the base branch so reviewing is better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
axiomatic_mcp/servers/equations/server.py (2)
356-359: Validation for equation structure still missing.• Line 359:
.get("equation")can returnNoneif the key is missing from the dict
• Creates a list with potentialNonevalues that will fail downstream
• No validation thatrelevant_equationsis well-formed before extractionThis issue was previously flagged but remains unaddressed.
Apply this diff to add validation:
doc_content = await _get_document_content(document) # Extract just the equation strings from the dict objects + # Validate structure first + for i, eq in enumerate(relevant_equations): + if not isinstance(eq, dict): + raise ToolError(f"Invalid equation at index {i}: expected dict, got {type(eq).__name__}") + if "equation" not in eq or not eq["equation"]: + raise ToolError(f"Invalid equation at index {i}: missing or empty 'equation' field") + equations_to_derive = [eq.get("equation") for eq in relevant_equations]
373-376: Long-running operation lacks timeout protection.• Operation blocks for 2-10 minutes (per line 327 description) without timeout
• If backend hangs or exceeds expected duration, client waits indefinitely
• No timeout handling in AxiomaticAPIClient.post() callThis issue was previously flagged but remains unaddressed.
To verify the AxiomaticAPIClient timeout behavior:
#!/bin/bash # Check if AxiomaticAPIClient respects TIMEOUT constant or allows per-call override rg -nP -A5 "class AxiomaticAPIClient" axiomatic_mcp/shared/api_client.py rg -nP -A10 "def post" axiomatic_mcp/shared/api_client.py
🧹 Nitpick comments (8)
axiomatic_mcp/shared/api_client.py (1)
17-21: Consider validating the overridden API URL.• Environment-provided URLs bypass validation, potentially causing runtime errors downstream
• Malformed URLs or incorrect schemes could fail silently until first request
• Recommend adding basic URL validation (scheme, format) when override is presentApply this diff to add validation:
# Allow overriding the API URL for local development base_url = os.getenv("AXIOMATIC_API_URL", API_URL) + + # Validate the base URL format + if not base_url.startswith(("http://", "https://")): + raise ValueError(f"Invalid AXIOMATIC_API_URL: must start with http:// or https://, got: {base_url}")axiomatic_mcp/servers/equations/server.py (1)
60-66: Heuristic may misclassify edge cases.• Line 61:
len(code_input) < 500 and "\n" not in code_inputcould misidentify:
- Short Python snippets as file paths (e.g.,
"import sys"is 10 chars, no newlines)- Long file paths (> 500 chars) as code strings
• Consider checkingPath(code_input).exists()first before length check
• Or add explicit parameter to disambiguateApply this diff to improve robustness:
# Check if it's a short string that might be a file path - if len(code_input) < 500 and "\n" not in code_input: - potential_path = Path(code_input) - if potential_path.exists() and potential_path.suffix.lower() == ".py": + potential_path = Path(code_input) + if potential_path.exists() and potential_path.suffix.lower() == ".py": - with Path.open(potential_path, encoding="utf-8") as f: - return f.read(), potential_path + with Path.open(potential_path, encoding="utf-8") as f: + return f.read(), potential_pathASML_Patent_Comprehensive_Verification_Report.md (3)
663-673: Add language specifiers to code blocks for better rendering.• Lines 663 and 670: Fenced code blocks lack language identifiers
• Improves syntax highlighting and accessibilityApply this diff:
-``` +```text I₁(k) = ½|E(k)|² + ½|E(-k)|² + |E(k)||E(-k)|cos(φ(k) - φ(-k)) I₂(k) = ½|E(k)|² + ½|E(-k)|² + |E(k)||E(-k)|cos(φ(k) - φ(-k)) ↑ ERROR - same signCorrected:
-+text
I₁(k) = ½|E(k)|² + ½|E(-k)|² + |E(k)||E(-k)|cos(φ(k) - φ(-k))
I₂(k) = ½|E(k)|² + ½|E(-k)|² - |E(k)||E(-k)|cos(φ(k) - φ(-k))
↑ CORRECTION - opposite sign
1098-1100: Format URLs as proper markdown links.• Bare URLs should be wrapped in angle brackets or converted to markdown links
• Improves rendering and accessibilityApply this diff:
### Software and Tools -6. SymPy Development Team, "SymPy: Python library for symbolic mathematics," Version 1.12, https://www.sympy.org +6. SymPy Development Team, "SymPy: Python library for symbolic mathematics," Version 1.12, <https://www.sympy.org> 7. Python Software Foundation, "Python Language Reference," version 3.11 -8. Axiomatic AI, "Mathematical Verification Platform," https://axiomatic.ai +8. Axiomatic AI, "Mathematical Verification Platform," <https://axiomatic.ai>
1125-1125: Use proper heading syntax instead of bold emphasis.• Line 1125: Bold text mimics a heading but isn't semantically marked as such
• Use markdown heading for better document structureApply this diff:
--- -**End of Report** +## End of ReportASML_Presentation_Deck.md (3)
28-40: Add language specifiers to code blocks.• Lines 28-40: ASCII art diagram lacks language specifier
• Usetextoryamlfor better renderingApply this diff:
-``` +```text Stage 1: BULK ANALYSIS ├─ 1 comprehensive verification call ├─ 10 equation categories analyzed
55-68: Add language specifiers to equation code blocks.• Multiple code blocks displaying equations lack language identifiers
• Lines 55-68, 574-591: Usetextfor plain equation formattingExample for lines 55-60:
**As Written in Patent** ❌ -``` +```text I₁(k) = ½[E(k)]² + ½[E(-k)]² + [E(k)][E(-k)]cos(Δφ) I₂(k) = ½[E(k)]² + ½[E(-k)]² + [E(k)][E(-k)]cos(Δφ)Apply similar changes to other equation blocks throughout the document.
Also applies to: 574-591
169-174: Add language specifiers to ASCII art and data blocks.• Multiple visualization and data blocks lack language identifiers
• Lines 169-174 (progress bars), 215-223 (statistics), etc.
• Usetextfor better rendering consistencyAlso applies to: 215-223, 347-353, 386-394, 441-460, 532-534
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (4)
ASML_Patent_Comprehensive_Verification_Report.md(1 hunks)ASML_Presentation_Deck.md(1 hunks)axiomatic_mcp/servers/equations/server.py(4 hunks)axiomatic_mcp/shared/api_client.py(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
ASML_Patent_Comprehensive_Verification_Report.md
663-663: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
670-670: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
1098-1098: Bare URL used
(MD034, no-bare-urls)
1100-1100: Bare URL used
(MD034, no-bare-urls)
1125-1125: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
ASML_Presentation_Deck.md
28-28: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
55-55: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
63-63: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
169-169: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
215-215: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
253-253: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
347-347: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
386-386: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
441-441: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
453-453: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
532-532: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
574-574: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
581-581: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
588-588: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (2)
axiomatic_mcp/servers/equations/server.py (2)
182-263: LGTM!• Proper use of helper function for code extraction
• Multipart/form-data encoding correctly configured
• Smart handling of pre-wrapped Mermaid code blocks
• File output path logic covers both file input and string input cases
• Error handling is appropriate
266-319: LGTM!• Clear separation of concerns (analysis vs execution)
• Explicit instructions requiring user approval before proceeding
• Safe dict access using .get() with defaults
• Proper formatting for user-facing output
• Error handling is appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
axiomatic_mcp/servers/equations/server.py (2)
356-362: Unresolved: Validate equation structure before extraction.• Line 359 blindly extracts
"equation"keys without validation
• Ifrelevant_equationscontains malformed dicts (missing "equation" key), this producesNonevalues that cause silent failures downstream
• This issue was flagged in a previous review and remains unaddressedApply this diff to validate structure:
doc_content = await _get_document_content(document) + # Validate structure before extraction + for i, eq in enumerate(relevant_equations): + if not isinstance(eq, dict): + raise ToolError(f"Invalid equation at index {i}: expected dict, got {type(eq).__name__}") + if "equation" not in eq or not eq["equation"]: + raise ToolError(f"Invalid equation at index {i}: missing or empty 'equation' key") + # Extract just the equation strings from the dict objects equations_to_derive = [eq.get("equation") for eq in relevant_equations]
373-376: Unresolved: Add timeout for long-running API call.• This synchronous API call blocks for 2-10 minutes (per line 327) with no timeout
• If the backend hangs or exceeds expected duration, the client waits indefinitely
• This issue was flagged in a previous review and remains unaddressedApply this diff to add timeout handling:
# Call synchronous execute endpoint (will block until complete) execute_response = AxiomaticAPIClient().post( "/equations/derive/all/markdown", data={"markdown": doc_content, "relevant_equations": equations_to_derive}, + timeout=600, # 10 minutes max, covers stated 2-10 minute range )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (1)
axiomatic_mcp/servers/equations/server.py(4 hunks)
🔇 Additional comments (4)
axiomatic_mcp/servers/equations/server.py (4)
44-69: LGTM: Clean helper implementation.• Follows the established pattern from
_get_document_content
• Validates file existence and extension appropriately
• Returns both code content and optional file path for downstream use
182-263: LGTM: Well-structured visualization tool.• Correctly uses the
_get_python_codehelper
• Multipart/form-data encoding viafilesparameter is appropriate for the backend endpoint
• Smart handling of pre-wrapped vs. unwrapped mermaid text (lines 245-250)
• Sensible output file naming relative to input
384-427: LGTM: File generation and result formatting.• Output directory creation with
mkdir(parents=True, exist_ok=True)is appropriate
• File writing includes equation context in docstring (line 396)
• Clear separation of successful vs. failed derivations
• Summary formatting provides actionable information with file links and error messages
71-89: LGTM: Clear workflow instructions.• Structured 2-step workflow is well-documented with explicit approval gate
• Instructions emphasize critical requirement for user approval before execution
• Feedback prompt correctly extended to include new tools:generate_derivation_graph,select_relevant_equations,derive_all_equations
| try: | ||
| doc_content = await _get_document_content(document) | ||
|
|
||
| analysis_response = AxiomaticAPIClient().post( | ||
| "/equations/select/markdown", | ||
| data={"markdown": doc_content}, | ||
| ) | ||
|
|
||
| relevant_equations = analysis_response.get("relevant_equations", []) | ||
| irrelevant_equations = analysis_response.get("irrelevant_equations", []) | ||
| summary = analysis_response.get("summary", "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Validate API response structure before iteration.
• Lines 297-298 extract lists from the response without validation
• If the API returns unexpected types (e.g., None, dict), the iteration at lines 305-314 will fail
• Add type checks and provide clear error messages
Apply this diff:
analysis_response = AxiomaticAPIClient().post(
"/equations/select/markdown",
data={"markdown": doc_content},
)
relevant_equations = analysis_response.get("relevant_equations", [])
irrelevant_equations = analysis_response.get("irrelevant_equations", [])
summary = analysis_response.get("summary", "")
+
+ # Validate response structure
+ if not isinstance(relevant_equations, list):
+ raise ToolError(f"Invalid response: relevant_equations must be a list, got {type(relevant_equations).__name__}")
+ if not isinstance(irrelevant_equations, list):
+ raise ToolError(f"Invalid response: irrelevant_equations must be a list, got {type(irrelevant_equations).__name__}")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try: | |
| doc_content = await _get_document_content(document) | |
| analysis_response = AxiomaticAPIClient().post( | |
| "/equations/select/markdown", | |
| data={"markdown": doc_content}, | |
| ) | |
| relevant_equations = analysis_response.get("relevant_equations", []) | |
| irrelevant_equations = analysis_response.get("irrelevant_equations", []) | |
| summary = analysis_response.get("summary", "") | |
| try: | |
| doc_content = await _get_document_content(document) | |
| analysis_response = AxiomaticAPIClient().post( | |
| "/equations/select/markdown", | |
| data={"markdown": doc_content}, | |
| ) | |
| relevant_equations = analysis_response.get("relevant_equations", []) | |
| irrelevant_equations = analysis_response.get("irrelevant_equations", []) | |
| summary = analysis_response.get("summary", "") | |
| # Validate response structure | |
| if not isinstance(relevant_equations, list): | |
| raise ToolError(f"Invalid response: relevant_equations must be a list, got {type(relevant_equations).__name__}") | |
| if not isinstance(irrelevant_equations, list): | |
| raise ToolError(f"Invalid response: irrelevant_equations must be a list, got {type(irrelevant_equations).__name__}") |
🤖 Prompt for AI Agents
In axiomatic_mcp/servers/equations/server.py around lines 289 to 299, the code
pulls "relevant_equations", "irrelevant_equations", and "summary" from the API
response without validating types; add validation after receiving
analysis_response: ensure analysis_response is a dict, confirm
relevant_equations and irrelevant_equations are lists (if not, either coerce to
empty list or raise/log a clear ValueError including the raw response), and
ensure summary is a string (coerce to "" if not); return or raise a descriptive
error if the structure is unexpected so the later iteration (lines ~305-314)
cannot fail silently.
New MCP Tools Added
1.
derive_all_equations_analyzePurpose: Intelligent equation categorization and analysis for parallel processing
Description:
This tool analyzes scientific documents (PDF, Markdown, or text) and automatically categorizes all equations found within them. It uses AI to determine which equations are suitable for symbolic derivation and which are not, providing detailed rationale for each decision.
Key Features:
Use Cases:
2.
derive_all_equations_executePurpose: Parallel batch execution of equation derivations
Description:
This tool executes the actual derivation process for all approved equations from the analysis step. It processes multiple equations in parallel batches, generating individual SymPy code files for each successful derivation.
Key Features:
.pyfiles for each equationUse Cases:
🔄 Workflow Integration
These tools work together in a structured 2-step workflow:
derive_all_equations_analyze→ User approval requiredderive_all_equations_execute→ Automatic execution after approvalThe workflow includes built-in safeguards requiring explicit user approval before proceeding to the computationally intensive execution phase, ensuring users have full control over the batch processing operation.
Both tools leverage the existing Axiomatic API infrastructure and follow the same document processing patterns as other tools in the equations server, maintaining consistency with the existing codebase architecture.