onetool-mcp 1.0.0b1__py3-none-any.whl → 1.0.0rc2__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.
Files changed (81) hide show
  1. onetool/cli.py +63 -4
  2. onetool_mcp-1.0.0rc2.dist-info/METADATA +266 -0
  3. onetool_mcp-1.0.0rc2.dist-info/RECORD +129 -0
  4. {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/licenses/LICENSE.txt +1 -1
  5. {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/licenses/NOTICE.txt +54 -64
  6. ot/__main__.py +6 -6
  7. ot/config/__init__.py +48 -46
  8. ot/config/global_templates/__init__.py +2 -2
  9. ot/config/{defaults → global_templates}/diagram-templates/api-flow.mmd +33 -33
  10. ot/config/{defaults → global_templates}/diagram-templates/c4-context.puml +30 -30
  11. ot/config/{defaults → global_templates}/diagram-templates/class-diagram.mmd +87 -87
  12. ot/config/{defaults → global_templates}/diagram-templates/feature-mindmap.mmd +70 -70
  13. ot/config/{defaults → global_templates}/diagram-templates/microservices.d2 +81 -81
  14. ot/config/{defaults → global_templates}/diagram-templates/project-gantt.mmd +37 -37
  15. ot/config/{defaults → global_templates}/diagram-templates/state-machine.mmd +42 -42
  16. ot/config/global_templates/diagram.yaml +167 -0
  17. ot/config/global_templates/onetool.yaml +3 -1
  18. ot/config/{defaults → global_templates}/prompts.yaml +102 -97
  19. ot/config/global_templates/security.yaml +31 -0
  20. ot/config/global_templates/servers.yaml +93 -12
  21. ot/config/global_templates/snippets.yaml +5 -26
  22. ot/config/{defaults → global_templates}/tool_templates/__init__.py +7 -7
  23. ot/config/loader.py +221 -105
  24. ot/config/mcp.py +5 -1
  25. ot/config/secrets.py +192 -190
  26. ot/decorators.py +116 -116
  27. ot/executor/__init__.py +35 -35
  28. ot/executor/base.py +16 -16
  29. ot/executor/fence_processor.py +83 -83
  30. ot/executor/linter.py +142 -142
  31. ot/executor/pep723.py +288 -288
  32. ot/executor/runner.py +20 -6
  33. ot/executor/simple.py +163 -163
  34. ot/executor/validator.py +603 -164
  35. ot/http_client.py +145 -145
  36. ot/logging/__init__.py +37 -37
  37. ot/logging/entry.py +213 -213
  38. ot/logging/format.py +191 -188
  39. ot/logging/span.py +349 -349
  40. ot/meta.py +236 -14
  41. ot/paths.py +32 -49
  42. ot/prompts.py +218 -218
  43. ot/proxy/manager.py +14 -2
  44. ot/registry/__init__.py +189 -189
  45. ot/registry/parser.py +269 -269
  46. ot/server.py +330 -315
  47. ot/shortcuts/__init__.py +15 -15
  48. ot/shortcuts/aliases.py +87 -87
  49. ot/shortcuts/snippets.py +258 -258
  50. ot/stats/__init__.py +35 -35
  51. ot/stats/html.py +2 -2
  52. ot/stats/reader.py +354 -354
  53. ot/stats/timing.py +57 -57
  54. ot/support.py +63 -63
  55. ot/tools.py +1 -1
  56. ot/utils/batch.py +161 -161
  57. ot/utils/cache.py +120 -120
  58. ot/utils/exceptions.py +23 -23
  59. ot/utils/factory.py +178 -179
  60. ot/utils/format.py +65 -65
  61. ot/utils/http.py +202 -202
  62. ot/utils/platform.py +45 -45
  63. ot/utils/truncate.py +69 -69
  64. ot_tools/__init__.py +4 -4
  65. ot_tools/_convert/__init__.py +12 -12
  66. ot_tools/_convert/pdf.py +254 -254
  67. ot_tools/diagram.yaml +167 -167
  68. ot_tools/scaffold.py +2 -2
  69. ot_tools/transform.py +124 -19
  70. ot_tools/web_fetch.py +94 -43
  71. onetool_mcp-1.0.0b1.dist-info/METADATA +0 -163
  72. onetool_mcp-1.0.0b1.dist-info/RECORD +0 -132
  73. ot/config/defaults/bench.yaml +0 -4
  74. ot/config/defaults/onetool.yaml +0 -25
  75. ot/config/defaults/servers.yaml +0 -7
  76. ot/config/defaults/snippets.yaml +0 -4
  77. ot_tools/firecrawl.py +0 -732
  78. {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/WHEEL +0 -0
  79. {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/entry_points.txt +0 -0
  80. /ot/config/{defaults → global_templates}/tool_templates/extension.py +0 -0
  81. /ot/config/{defaults → global_templates}/tool_templates/isolated.py +0 -0
ot/executor/__init__.py CHANGED
@@ -1,35 +1,35 @@
1
- """Execution engines for OneTool.
2
-
3
- Provides direct host execution via SimpleExecutor.
4
- The unified runner provides a single entry point for all command execution.
5
- """
6
-
7
- from ot.executor.base import ExecutionResult
8
- from ot.executor.fence_processor import strip_fences
9
- from ot.executor.runner import (
10
- CommandResult,
11
- PreparedCommand,
12
- execute_command,
13
- execute_python_code,
14
- prepare_command,
15
- )
16
- from ot.executor.simple import SimpleExecutor
17
- from ot.executor.validator import (
18
- ValidationResult,
19
- validate_for_exec,
20
- validate_python_code,
21
- )
22
-
23
- __all__ = [
24
- "CommandResult",
25
- "ExecutionResult",
26
- "PreparedCommand",
27
- "SimpleExecutor",
28
- "ValidationResult",
29
- "execute_command",
30
- "execute_python_code",
31
- "prepare_command",
32
- "strip_fences",
33
- "validate_for_exec",
34
- "validate_python_code",
35
- ]
1
+ """Execution engines for OneTool.
2
+
3
+ Provides direct host execution via SimpleExecutor.
4
+ The unified runner provides a single entry point for all command execution.
5
+ """
6
+
7
+ from ot.executor.base import ExecutionResult
8
+ from ot.executor.fence_processor import strip_fences
9
+ from ot.executor.runner import (
10
+ CommandResult,
11
+ PreparedCommand,
12
+ execute_command,
13
+ execute_python_code,
14
+ prepare_command,
15
+ )
16
+ from ot.executor.simple import SimpleExecutor
17
+ from ot.executor.validator import (
18
+ ValidationResult,
19
+ validate_for_exec,
20
+ validate_python_code,
21
+ )
22
+
23
+ __all__ = [
24
+ "CommandResult",
25
+ "ExecutionResult",
26
+ "PreparedCommand",
27
+ "SimpleExecutor",
28
+ "ValidationResult",
29
+ "execute_command",
30
+ "execute_python_code",
31
+ "prepare_command",
32
+ "strip_fences",
33
+ "validate_for_exec",
34
+ "validate_python_code",
35
+ ]
ot/executor/base.py CHANGED
@@ -1,16 +1,16 @@
1
- """Base types for executor module."""
2
-
3
- from __future__ import annotations
4
-
5
- from dataclasses import dataclass
6
-
7
-
8
- @dataclass
9
- class ExecutionResult:
10
- """Result from executing a tool."""
11
-
12
- success: bool
13
- result: str
14
- duration_seconds: float = 0.0
15
- executor: str = "simple"
16
- error_type: str | None = None
1
+ """Base types for executor module."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+
8
+ @dataclass
9
+ class ExecutionResult:
10
+ """Result from executing a tool."""
11
+
12
+ success: bool
13
+ result: str
14
+ duration_seconds: float = 0.0
15
+ executor: str = "simple"
16
+ error_type: str | None = None
@@ -1,83 +1,83 @@
1
- """Fence processing for command execution.
2
-
3
- Handles stripping of:
4
- - Execution trigger prefixes (__ot, __onetool, mcp__onetool__run)
5
- - Markdown code fences (triple backticks with/without language)
6
- - Inline backticks (single and double)
7
-
8
- Used by the runner to clean commands before execution.
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- import re
14
-
15
-
16
- def strip_fences(command: str) -> tuple[str, bool]:
17
- """Strip execution prefixes, markdown code fences, and inline backticks.
18
-
19
- Execution trigger prefixes (stripped first):
20
- __ot - short name, default tool
21
- __ot__run - short name, explicit tool call
22
- __onetool - full name, default tool
23
- __onetool__run - full name, explicit tool call
24
- mcp__onetool__run - explicit MCP call
25
-
26
- Each prefix supports three invocation styles:
27
- <prefix> func(arg="value") - simple call
28
- <prefix> `code` - inline backticks
29
- <prefix> + code fence - multi-line code fence
30
-
31
- Note: mcp__ot__run is NOT a valid prefix.
32
-
33
- Markdown fences (stripped after prefix):
34
- ```python
35
- code here
36
- ```
37
-
38
- `code here`
39
-
40
- `` `code here` ``
41
-
42
- Args:
43
- command: Raw command string that may contain prefixes and fences
44
-
45
- Returns:
46
- Tuple of (stripped command, whether anything was stripped)
47
- """
48
- stripped = command.strip()
49
- anything_stripped = False
50
-
51
- # Strip execution trigger prefixes:
52
- # - __ot, __ot__run (short name)
53
- # - __onetool, __onetool__run (full name)
54
- # - mcp__onetool__run (explicit MCP call)
55
- # Note: mcp__ot__run is NOT valid
56
- prefix_pattern = r"^(?:mcp__onetool__run|__onetool(?:__run)?|__ot(?:__run)?)\s*"
57
- match = re.match(prefix_pattern, stripped)
58
- if match:
59
- stripped = stripped[match.end() :].strip()
60
- anything_stripped = True
61
-
62
- # Handle triple backtick fenced blocks
63
- if stripped.startswith("```"):
64
- first_newline = stripped.find("\n")
65
- if first_newline != -1 and stripped.endswith("```"):
66
- content = stripped[first_newline + 1 : -3].strip()
67
- return content, True
68
-
69
- # Handle double backtick fenced blocks: `` `code` ``
70
- if stripped.startswith("`` `") and stripped.endswith("` ``"):
71
- content = stripped[4:-4].strip()
72
- return content, True
73
-
74
- if stripped.startswith("``") and stripped.endswith("``"):
75
- content = stripped[2:-2].strip()
76
- return content, True
77
-
78
- # Handle inline single backticks: `code`
79
- if stripped.startswith("`") and stripped.endswith("`") and stripped.count("`") == 2:
80
- content = stripped[1:-1].strip()
81
- return content, True
82
-
83
- return stripped, anything_stripped
1
+ """Fence processing for command execution.
2
+
3
+ Handles stripping of:
4
+ - Execution trigger prefixes (__ot, __onetool, mcp__onetool__run)
5
+ - Markdown code fences (triple backticks with/without language)
6
+ - Inline backticks (single and double)
7
+
8
+ Used by the runner to clean commands before execution.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import re
14
+
15
+
16
+ def strip_fences(command: str) -> tuple[str, bool]:
17
+ """Strip execution prefixes, markdown code fences, and inline backticks.
18
+
19
+ Execution trigger prefixes (stripped first):
20
+ __ot - short name, default tool
21
+ __ot__run - short name, explicit tool call
22
+ __onetool - full name, default tool
23
+ __onetool__run - full name, explicit tool call
24
+ mcp__onetool__run - explicit MCP call
25
+
26
+ Each prefix supports three invocation styles:
27
+ <prefix> func(arg="value") - simple call
28
+ <prefix> `code` - inline backticks
29
+ <prefix> + code fence - multi-line code fence
30
+
31
+ Note: mcp__ot__run is NOT a valid prefix.
32
+
33
+ Markdown fences (stripped after prefix):
34
+ ```python
35
+ code here
36
+ ```
37
+
38
+ `code here`
39
+
40
+ `` `code here` ``
41
+
42
+ Args:
43
+ command: Raw command string that may contain prefixes and fences
44
+
45
+ Returns:
46
+ Tuple of (stripped command, whether anything was stripped)
47
+ """
48
+ stripped = command.strip()
49
+ anything_stripped = False
50
+
51
+ # Strip execution trigger prefixes:
52
+ # - __ot, __ot__run (short name)
53
+ # - __onetool, __onetool__run (full name)
54
+ # - mcp__onetool__run (explicit MCP call)
55
+ # Note: mcp__ot__run is NOT valid
56
+ prefix_pattern = r"^(?:mcp__onetool__run|__onetool(?:__run)?|__ot(?:__run)?)\s*"
57
+ match = re.match(prefix_pattern, stripped)
58
+ if match:
59
+ stripped = stripped[match.end() :].strip()
60
+ anything_stripped = True
61
+
62
+ # Handle triple backtick fenced blocks
63
+ if stripped.startswith("```"):
64
+ first_newline = stripped.find("\n")
65
+ if first_newline != -1 and stripped.endswith("```"):
66
+ content = stripped[first_newline + 1 : -3].strip()
67
+ return content, True
68
+
69
+ # Handle double backtick fenced blocks: `` `code` ``
70
+ if stripped.startswith("`` `") and stripped.endswith("` ``"):
71
+ content = stripped[4:-4].strip()
72
+ return content, True
73
+
74
+ if stripped.startswith("``") and stripped.endswith("``"):
75
+ content = stripped[2:-2].strip()
76
+ return content, True
77
+
78
+ # Handle inline single backticks: `code`
79
+ if stripped.startswith("`") and stripped.endswith("`") and stripped.count("`") == 2:
80
+ content = stripped[1:-1].strip()
81
+ return content, True
82
+
83
+ return stripped, anything_stripped
ot/executor/linter.py CHANGED
@@ -1,142 +1,142 @@
1
- """Optional Ruff linting integration for OneTool.
2
-
3
- Provides style warnings (non-blocking) using Ruff linter if installed.
4
- Falls back gracefully if Ruff is not available.
5
-
6
- Example:
7
- result = lint_code(code)
8
- if result.available:
9
- for warning in result.warnings:
10
- print(f"Style warning: {warning}")
11
- """
12
-
13
- from __future__ import annotations
14
-
15
- import contextlib
16
- import subprocess
17
- import tempfile
18
- from dataclasses import dataclass, field
19
- from pathlib import Path
20
-
21
- from loguru import logger
22
-
23
-
24
- @dataclass
25
- class LintResult:
26
- """Result of linting operation."""
27
-
28
- available: bool = False # Whether Ruff is available
29
- warnings: list[str] = field(default_factory=list)
30
- error: str | None = None # Error message if linting failed
31
-
32
-
33
- def _check_ruff_available() -> bool:
34
- """Check if Ruff is available on the system."""
35
- try:
36
- result = subprocess.run(
37
- ["ruff", "--version"],
38
- capture_output=True,
39
- text=True,
40
- timeout=5,
41
- )
42
- return result.returncode == 0
43
- except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
44
- return False
45
-
46
-
47
- # Cache Ruff availability check
48
- _ruff_available: bool | None = None
49
-
50
-
51
- def is_ruff_available() -> bool:
52
- """Check if Ruff linter is available (cached)."""
53
- global _ruff_available
54
- if _ruff_available is None:
55
- _ruff_available = _check_ruff_available()
56
- return _ruff_available
57
-
58
-
59
- def lint_code(
60
- code: str,
61
- select: list[str] | None = None,
62
- ignore: list[str] | None = None,
63
- ) -> LintResult:
64
- """Lint Python code using Ruff.
65
-
66
- Args:
67
- code: Python code to lint
68
- select: Rule codes to enable (e.g., ["E", "F", "W"])
69
- ignore: Rule codes to ignore (e.g., ["E501"])
70
-
71
- Returns:
72
- LintResult with warnings if Ruff is available
73
- """
74
- result = LintResult()
75
-
76
- if not is_ruff_available():
77
- result.available = False
78
- return result
79
-
80
- result.available = True
81
-
82
- # Write code to temp file for Ruff
83
- try:
84
- with tempfile.NamedTemporaryFile(
85
- mode="w",
86
- suffix=".py",
87
- delete=False,
88
- ) as f:
89
- f.write(code)
90
- temp_path = Path(f.name)
91
-
92
- # Build Ruff command
93
- cmd = ["ruff", "check", str(temp_path), "--output-format=text"]
94
-
95
- if select:
96
- cmd.extend(["--select", ",".join(select)])
97
- if ignore:
98
- cmd.extend(["--ignore", ",".join(ignore)])
99
-
100
- # Run Ruff
101
- proc = subprocess.run(
102
- cmd,
103
- capture_output=True,
104
- text=True,
105
- timeout=30,
106
- )
107
-
108
- # Parse output - each line is a warning
109
- if proc.stdout:
110
- for line in proc.stdout.strip().split("\n"):
111
- if line.strip():
112
- # Remove temp file path from output
113
- warning = line.replace(str(temp_path), "<code>")
114
- result.warnings.append(warning)
115
-
116
- except subprocess.TimeoutExpired:
117
- result.error = "Ruff linting timed out"
118
- logger.warning("Ruff linting timed out")
119
- except OSError as e:
120
- result.error = f"Failed to run Ruff: {e}"
121
- logger.warning(f"Failed to run Ruff: {e}")
122
- finally:
123
- # Clean up temp file
124
- with contextlib.suppress(NameError, OSError):
125
- temp_path.unlink()
126
-
127
- return result
128
-
129
-
130
- def lint_code_quick(code: str) -> list[str]:
131
- """Quick lint that returns just the warnings list.
132
-
133
- Convenience function for simple use cases.
134
-
135
- Args:
136
- code: Python code to lint
137
-
138
- Returns:
139
- List of warning strings (empty if Ruff unavailable)
140
- """
141
- result = lint_code(code)
142
- return result.warnings
1
+ """Optional Ruff linting integration for OneTool.
2
+
3
+ Provides style warnings (non-blocking) using Ruff linter if installed.
4
+ Falls back gracefully if Ruff is not available.
5
+
6
+ Example:
7
+ result = lint_code(code)
8
+ if result.available:
9
+ for warning in result.warnings:
10
+ print(f"Style warning: {warning}")
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import contextlib
16
+ import subprocess
17
+ import tempfile
18
+ from dataclasses import dataclass, field
19
+ from pathlib import Path
20
+
21
+ from loguru import logger
22
+
23
+
24
+ @dataclass
25
+ class LintResult:
26
+ """Result of linting operation."""
27
+
28
+ available: bool = False # Whether Ruff is available
29
+ warnings: list[str] = field(default_factory=list)
30
+ error: str | None = None # Error message if linting failed
31
+
32
+
33
+ def _check_ruff_available() -> bool:
34
+ """Check if Ruff is available on the system."""
35
+ try:
36
+ result = subprocess.run(
37
+ ["ruff", "--version"],
38
+ capture_output=True,
39
+ text=True,
40
+ timeout=5,
41
+ )
42
+ return result.returncode == 0
43
+ except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
44
+ return False
45
+
46
+
47
+ # Cache Ruff availability check
48
+ _ruff_available: bool | None = None
49
+
50
+
51
+ def is_ruff_available() -> bool:
52
+ """Check if Ruff linter is available (cached)."""
53
+ global _ruff_available
54
+ if _ruff_available is None:
55
+ _ruff_available = _check_ruff_available()
56
+ return _ruff_available
57
+
58
+
59
+ def lint_code(
60
+ code: str,
61
+ select: list[str] | None = None,
62
+ ignore: list[str] | None = None,
63
+ ) -> LintResult:
64
+ """Lint Python code using Ruff.
65
+
66
+ Args:
67
+ code: Python code to lint
68
+ select: Rule codes to enable (e.g., ["E", "F", "W"])
69
+ ignore: Rule codes to ignore (e.g., ["E501"])
70
+
71
+ Returns:
72
+ LintResult with warnings if Ruff is available
73
+ """
74
+ result = LintResult()
75
+
76
+ if not is_ruff_available():
77
+ result.available = False
78
+ return result
79
+
80
+ result.available = True
81
+
82
+ # Write code to temp file for Ruff
83
+ try:
84
+ with tempfile.NamedTemporaryFile(
85
+ mode="w",
86
+ suffix=".py",
87
+ delete=False,
88
+ ) as f:
89
+ f.write(code)
90
+ temp_path = Path(f.name)
91
+
92
+ # Build Ruff command
93
+ cmd = ["ruff", "check", str(temp_path), "--output-format=text"]
94
+
95
+ if select:
96
+ cmd.extend(["--select", ",".join(select)])
97
+ if ignore:
98
+ cmd.extend(["--ignore", ",".join(ignore)])
99
+
100
+ # Run Ruff
101
+ proc = subprocess.run(
102
+ cmd,
103
+ capture_output=True,
104
+ text=True,
105
+ timeout=30,
106
+ )
107
+
108
+ # Parse output - each line is a warning
109
+ if proc.stdout:
110
+ for line in proc.stdout.strip().split("\n"):
111
+ if line.strip():
112
+ # Remove temp file path from output
113
+ warning = line.replace(str(temp_path), "<code>")
114
+ result.warnings.append(warning)
115
+
116
+ except subprocess.TimeoutExpired:
117
+ result.error = "Ruff linting timed out"
118
+ logger.warning("Ruff linting timed out")
119
+ except OSError as e:
120
+ result.error = f"Failed to run Ruff: {e}"
121
+ logger.warning(f"Failed to run Ruff: {e}")
122
+ finally:
123
+ # Clean up temp file
124
+ with contextlib.suppress(NameError, OSError):
125
+ temp_path.unlink()
126
+
127
+ return result
128
+
129
+
130
+ def lint_code_quick(code: str) -> list[str]:
131
+ """Quick lint that returns just the warnings list.
132
+
133
+ Convenience function for simple use cases.
134
+
135
+ Args:
136
+ code: Python code to lint
137
+
138
+ Returns:
139
+ List of warning strings (empty if Ruff unavailable)
140
+ """
141
+ result = lint_code(code)
142
+ return result.warnings