comptext-codex 5.0.0__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.
@@ -0,0 +1,248 @@
1
+ """CompText DSL Executor - Executes parsed CompText commands."""
2
+
3
+ from typing import Any, Dict, List, Optional, Callable
4
+ from dataclasses import dataclass
5
+ import logging
6
+
7
+ from .parser import CompTextCommand, CompTextParser
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ @dataclass
13
+ class ExecutionResult:
14
+ """Result of command execution."""
15
+ success: bool
16
+ result: Any
17
+ error: Optional[str] = None
18
+ metadata: Dict[str, Any] = None
19
+
20
+ def __post_init__(self):
21
+ if self.metadata is None:
22
+ self.metadata = {}
23
+
24
+
25
+ class CompTextExecutor:
26
+ """Executes CompText commands by dispatching to appropriate modules."""
27
+
28
+ def __init__(self, codex_dir: Optional[str] = None):
29
+ """Initialize executor.
30
+
31
+ Args:
32
+ codex_dir: Path to codex directory for loading definitions (legacy)
33
+ """
34
+ self.codex_dir = codex_dir
35
+ self.parser = CompTextParser(codex_dir=codex_dir)
36
+ self._module_instances: Dict[str, Any] = {}
37
+ self._command_handlers: Dict[str, Callable] = {}
38
+ self._registry = None
39
+ self._load_modules()
40
+
41
+ def _load_modules(self):
42
+ """Load modules via the auto-registration registry."""
43
+ try:
44
+ from .registry import ensure_modules_loaded, registry
45
+ ensure_modules_loaded()
46
+ self._registry = registry
47
+ # Pre-populate instances for all registered modules
48
+ for code in registry.list_module_codes():
49
+ self._module_instances[code] = registry.get_instance(code)
50
+ logger.debug("Loaded %d modules from registry", len(self._module_instances))
51
+ except ImportError as e:
52
+ logger.warning("Failed to load registry, falling back to legacy: %s", e)
53
+ self._load_modules_legacy()
54
+
55
+ def _load_modules_legacy(self):
56
+ """Fallback: Dynamically load module implementations via importlib."""
57
+ import importlib
58
+ for code in "ABCDEFGHIJKLM":
59
+ try:
60
+ module_name = f"comptext_codex.modules.module_{code.lower()}"
61
+ module = importlib.import_module(module_name)
62
+ if hasattr(module, "get_module"):
63
+ self._module_instances[code] = module.get_module()
64
+ else:
65
+ self._module_instances[code] = module
66
+ except ImportError as e:
67
+ logger.debug("Module %s not implemented: %s", code, e)
68
+ self._module_instances[code] = None
69
+
70
+ def execute(self, command_string: str, context: Optional[Dict[str, Any]] = None) -> List[ExecutionResult]:
71
+ """Execute CompText command(s).
72
+
73
+ Args:
74
+ command_string: Raw CompText command(s)
75
+ context: Optional execution context with variables
76
+
77
+ Returns:
78
+ List of execution results for each command
79
+
80
+ Examples:
81
+ >>> executor = CompTextExecutor()
82
+ >>> results = executor.execute("@A:compress The quick brown fox")
83
+ >>> print(results[0].result)
84
+ """
85
+ context = context or {}
86
+
87
+ # Parse commands
88
+ commands = self.parser.parse(command_string)
89
+
90
+ if not commands:
91
+ return [ExecutionResult(
92
+ success=False,
93
+ result=None,
94
+ error="Failed to parse command"
95
+ )]
96
+
97
+ # Execute each command in sequence
98
+ results = []
99
+ execution_context = context.copy()
100
+
101
+ for cmd in commands:
102
+ result = self._execute_single(cmd, execution_context)
103
+ results.append(result)
104
+
105
+ # Update context with result for chained commands
106
+ if result.success:
107
+ execution_context['_last_result'] = result.result
108
+
109
+ return results
110
+
111
+ def _execute_single(self, cmd: CompTextCommand, context: Dict[str, Any]) -> ExecutionResult:
112
+ """Execute a single command.
113
+
114
+ Args:
115
+ cmd: Parsed command
116
+ context: Execution context
117
+
118
+ Returns:
119
+ Execution result
120
+ """
121
+ try:
122
+ # Get module instance (from registry or legacy)
123
+ module = self._module_instances.get(cmd.module)
124
+
125
+ if module is None:
126
+ return self._execute_fallback(cmd, context)
127
+
128
+ # Find command handler
129
+ handler_name = f"execute_{cmd.command.lower()}"
130
+
131
+ if hasattr(module, handler_name):
132
+ handler = getattr(module, handler_name)
133
+ result = handler(*cmd.args, context=context, **cmd.kwargs)
134
+
135
+ return ExecutionResult(
136
+ success=True,
137
+ result=result,
138
+ metadata={
139
+ 'module': cmd.module,
140
+ 'command': cmd.command
141
+ }
142
+ )
143
+ elif hasattr(module, 'execute'):
144
+ # Generic execute method
145
+ try:
146
+ result = module.execute(cmd, context)
147
+ return ExecutionResult(
148
+ success=True,
149
+ result=result,
150
+ metadata={
151
+ 'module': cmd.module,
152
+ 'command': cmd.command
153
+ }
154
+ )
155
+ except NotImplementedError:
156
+ return self._execute_fallback(cmd, context)
157
+ else:
158
+ return self._execute_fallback(cmd, context)
159
+
160
+ except Exception as e:
161
+ logger.error(f"Error executing {cmd.module}:{cmd.command}: {e}")
162
+ return ExecutionResult(
163
+ success=False,
164
+ result=None,
165
+ error=str(e),
166
+ metadata={
167
+ 'module': cmd.module,
168
+ 'command': cmd.command
169
+ }
170
+ )
171
+
172
+ def _execute_fallback(self, cmd: CompTextCommand, context: Dict[str, Any]) -> ExecutionResult:
173
+ """Fallback execution for unimplemented commands.
174
+
175
+ Returns a mock result that describes what would be executed.
176
+ """
177
+ return ExecutionResult(
178
+ success=True,
179
+ result={
180
+ 'status': 'simulated',
181
+ 'message': f"Command {cmd.module}:{cmd.command} would execute with args={cmd.args}, kwargs={cmd.kwargs}",
182
+ 'module': cmd.module,
183
+ 'command': cmd.command,
184
+ 'args': cmd.args,
185
+ 'kwargs': cmd.kwargs
186
+ },
187
+ metadata={
188
+ 'simulated': True,
189
+ 'module': cmd.module,
190
+ 'command': cmd.command
191
+ }
192
+ )
193
+
194
+ def register_handler(self, module: str, command: str, handler: Callable):
195
+ """Register a custom command handler.
196
+
197
+ Args:
198
+ module: Module code (A-M)
199
+ command: Command name
200
+ handler: Callable that executes the command
201
+ """
202
+ key = f"{module}:{command}"
203
+ self._command_handlers[key] = handler
204
+
205
+ def get_available_commands(self) -> List[Dict[str, Any]]:
206
+ """Get list of available commands.
207
+
208
+ Returns:
209
+ List of command metadata dictionaries
210
+ """
211
+ # Prefer registry metadata (includes descriptions, aliases, etc.)
212
+ if self._registry is not None:
213
+ return [cmd.to_dict() for cmd in self._registry.all_command_meta()]
214
+
215
+ # Fallback: introspect module instances
216
+ commands = []
217
+ for module_code, module in self._module_instances.items():
218
+ if module is None:
219
+ continue
220
+ if hasattr(module, "get_commands"):
221
+ commands.extend(module.get_commands())
222
+ else:
223
+ for attr_name in dir(module):
224
+ if attr_name.startswith("execute_"):
225
+ command_name = attr_name[8:]
226
+ commands.append({
227
+ "module": module_code,
228
+ "command": command_name,
229
+ "syntax": f"@{module_code}:{command_name}",
230
+ })
231
+ return commands
232
+
233
+
234
+ # Convenience function
235
+ def execute(command_string: str, context: Optional[Dict[str, Any]] = None,
236
+ codex_dir: Optional[str] = None) -> List[ExecutionResult]:
237
+ """Execute CompText command(s).
238
+
239
+ Args:
240
+ command_string: Raw CompText command(s)
241
+ context: Optional execution context
242
+ codex_dir: Optional path to codex directory
243
+
244
+ Returns:
245
+ List of execution results
246
+ """
247
+ executor = CompTextExecutor(codex_dir=codex_dir)
248
+ return executor.execute(command_string, context=context)
@@ -0,0 +1,343 @@
1
+ """CompText V5.0 ULTRA MCP Server Implementation."""
2
+
3
+ import json
4
+ from typing import Any, Dict, List, Optional
5
+ from dataclasses import dataclass, asdict
6
+
7
+ try:
8
+ from mcp import Server, Tool, types
9
+ MCP_AVAILABLE = True
10
+ except ImportError:
11
+ MCP_AVAILABLE = False
12
+ # Fallback for when MCP is not installed
13
+ class Server:
14
+ pass
15
+ class Tool:
16
+ pass
17
+
18
+ from .parser_v5 import CompTextParserV5, CompTextCommandV5
19
+
20
+
21
+ @dataclass
22
+ class MCPToolResult:
23
+ """Result from an MCP tool execution."""
24
+ success: bool
25
+ data: Any
26
+ error: Optional[str] = None
27
+ metadata: Optional[Dict[str, Any]] = None
28
+
29
+
30
+ class CompTextMCPServer:
31
+ """MCP Server for CompText V5.0 ULTRA Protocol.
32
+
33
+ Provides tools for parsing, encoding, and analyzing V5.0 ULTRA commands
34
+ through the Model Context Protocol.
35
+ """
36
+
37
+ def __init__(self):
38
+ """Initialize MCP server."""
39
+ if not MCP_AVAILABLE:
40
+ raise ImportError("MCP package not installed. Install with: pip install mcp")
41
+
42
+ self.parser = CompTextParserV5()
43
+ self.server = Server("comptext-v5-ultra")
44
+
45
+ # Register tools
46
+ self._register_tools()
47
+
48
+ def _register_tools(self):
49
+ """Register MCP tools."""
50
+
51
+ @self.server.tool(
52
+ name="parse_v5",
53
+ description="Parse a CompText V5.0 ULTRA command into structured format",
54
+ parameters={
55
+ "command": {
56
+ "type": "string",
57
+ "description": "V5.0 ULTRA command to parse (e.g., 'C;P:FIB' or 'B:[D:SUM]|[C;P:FIB]')"
58
+ }
59
+ }
60
+ )
61
+ async def parse_v5(command: str) -> Dict[str, Any]:
62
+ """Parse V5.0 ULTRA command."""
63
+ try:
64
+ results = self.parser.parse(command)
65
+
66
+ commands = []
67
+ for cmd in results:
68
+ commands.append({
69
+ "command": self.parser.COMMANDS.get(cmd.command, cmd.command),
70
+ "command_char": cmd.command,
71
+ "language": self.parser.LANGUAGES.get(cmd.language, cmd.language) if cmd.language else None,
72
+ "language_char": cmd.language,
73
+ "modifiers": [self.parser.MODIFIERS.get(m, m) for m in cmd.modifiers] if cmd.modifiers else [],
74
+ "modifier_chars": cmd.modifiers,
75
+ "task": cmd.task,
76
+ "raw": cmd.raw
77
+ })
78
+
79
+ return {
80
+ "success": True,
81
+ "count": len(commands),
82
+ "commands": commands
83
+ }
84
+ except Exception as e:
85
+ return {
86
+ "success": False,
87
+ "error": str(e)
88
+ }
89
+
90
+ @self.server.tool(
91
+ name="encode_v5",
92
+ description="Encode a command to V5.0 ULTRA format",
93
+ parameters={
94
+ "command": {
95
+ "type": "string",
96
+ "description": "Command name (e.g., 'CODE', 'TEST', 'DOCUMENT')"
97
+ },
98
+ "language": {
99
+ "type": "string",
100
+ "description": "Optional language (e.g., 'PYTHON', 'JAVASCRIPT')",
101
+ "optional": True
102
+ },
103
+ "modifiers": {
104
+ "type": "array",
105
+ "description": "Optional modifiers (e.g., ['ROBUST', 'CONCISE'])",
106
+ "optional": True
107
+ },
108
+ "task": {
109
+ "type": "string",
110
+ "description": "Optional task name",
111
+ "optional": True
112
+ }
113
+ }
114
+ )
115
+ async def encode_v5(command: str, language: Optional[str] = None,
116
+ modifiers: Optional[List[str]] = None,
117
+ task: Optional[str] = None) -> Dict[str, Any]:
118
+ """Encode command to V5.0 ULTRA format."""
119
+ try:
120
+ result = self.parser.encode(
121
+ command.upper(),
122
+ language.upper() if language else None,
123
+ [m.upper() for m in modifiers] if modifiers else None,
124
+ task
125
+ )
126
+
127
+ return {
128
+ "success": True,
129
+ "v5_command": result,
130
+ "input": {
131
+ "command": command,
132
+ "language": language,
133
+ "modifiers": modifiers,
134
+ "task": task
135
+ }
136
+ }
137
+ except Exception as e:
138
+ return {
139
+ "success": False,
140
+ "error": str(e)
141
+ }
142
+
143
+ @self.server.tool(
144
+ name="encode_batch_v5",
145
+ description="Encode multiple commands to V5.0 ULTRA batch format",
146
+ parameters={
147
+ "commands": {
148
+ "type": "array",
149
+ "description": "Array of command objects with command, language, modifiers, task"
150
+ }
151
+ }
152
+ )
153
+ async def encode_batch_v5(commands: List[Dict[str, Any]]) -> Dict[str, Any]:
154
+ """Encode batch of commands to V5.0 ULTRA format."""
155
+ try:
156
+ batch_input = []
157
+ for cmd_dict in commands:
158
+ batch_input.append((
159
+ cmd_dict.get('command', '').upper(),
160
+ cmd_dict.get('language', '').upper() if cmd_dict.get('language') else None,
161
+ [m.upper() for m in cmd_dict.get('modifiers', [])] if cmd_dict.get('modifiers') else None,
162
+ cmd_dict.get('task')
163
+ ))
164
+
165
+ result = self.parser.encode_batch(batch_input)
166
+
167
+ return {
168
+ "success": True,
169
+ "v5_batch": result,
170
+ "count": len(commands)
171
+ }
172
+ except Exception as e:
173
+ return {
174
+ "success": False,
175
+ "error": str(e)
176
+ }
177
+
178
+ @self.server.tool(
179
+ name="calculate_token_reduction",
180
+ description="Calculate token reduction statistics for V5.0 ULTRA",
181
+ parameters={
182
+ "natural_language": {
183
+ "type": "string",
184
+ "description": "Original natural language request"
185
+ },
186
+ "v5_command": {
187
+ "type": "string",
188
+ "description": "V5.0 ULTRA encoded command"
189
+ }
190
+ }
191
+ )
192
+ async def calculate_token_reduction(natural_language: str, v5_command: str) -> Dict[str, Any]:
193
+ """Calculate token reduction statistics."""
194
+ try:
195
+ stats = self.parser.calculate_token_reduction(natural_language, v5_command)
196
+
197
+ return {
198
+ "success": True,
199
+ "statistics": stats
200
+ }
201
+ except Exception as e:
202
+ return {
203
+ "success": False,
204
+ "error": str(e)
205
+ }
206
+
207
+ @self.server.tool(
208
+ name="convert_v5_to_v4",
209
+ description="Convert V5.0 ULTRA command to V4.0 format",
210
+ parameters={
211
+ "v5_command": {
212
+ "type": "string",
213
+ "description": "V5.0 ULTRA command to convert"
214
+ }
215
+ }
216
+ )
217
+ async def convert_v5_to_v4(v5_command: str) -> Dict[str, Any]:
218
+ """Convert V5 to V4 format."""
219
+ try:
220
+ results = self.parser.parse(v5_command)
221
+
222
+ v4_commands = []
223
+ for cmd in results:
224
+ v4_format = self.parser.to_v4_format(cmd)
225
+ v4_commands.append(v4_format)
226
+
227
+ return {
228
+ "success": True,
229
+ "v5_input": v5_command,
230
+ "v4_output": v4_commands,
231
+ "count": len(v4_commands)
232
+ }
233
+ except Exception as e:
234
+ return {
235
+ "success": False,
236
+ "error": str(e)
237
+ }
238
+
239
+ @self.server.tool(
240
+ name="get_v5_reference",
241
+ description="Get V5.0 ULTRA syntax reference (commands, languages, modifiers)",
242
+ parameters={}
243
+ )
244
+ async def get_v5_reference() -> Dict[str, Any]:
245
+ """Get V5.0 ULTRA reference."""
246
+ return {
247
+ "success": True,
248
+ "version": "5.0.0",
249
+ "commands": {char: full for char, full in self.parser.COMMANDS.items()},
250
+ "languages": {char: full for char, full in self.parser.LANGUAGES.items()},
251
+ "modifiers": {char: full for char, full in self.parser.MODIFIERS.items()},
252
+ "syntax": {
253
+ "simple": "CMD;LANG:TASK",
254
+ "with_modifiers": "CMD;LANG;MOD:TASK",
255
+ "batch": "B:[CMD1]|[CMD2]|[CMD3]"
256
+ },
257
+ "examples": [
258
+ {"v5": "C;P:FIB", "description": "Code Python Fibonacci"},
259
+ {"v5": "T;P;R:FIB", "description": "Test Python (Robust) Fibonacci"},
260
+ {"v5": "B:[D:SUM]|[C;P:FIB]|[E;C:WHY]", "description": "Batch: Document + Code + Explain"}
261
+ ]
262
+ }
263
+
264
+ @self.server.tool(
265
+ name="benchmark_v5",
266
+ description="Run benchmark comparing natural language to V5.0 ULTRA",
267
+ parameters={
268
+ "examples": {
269
+ "type": "array",
270
+ "description": "Array of {natural, v5} example pairs"
271
+ }
272
+ }
273
+ )
274
+ async def benchmark_v5(examples: List[Dict[str, str]]) -> Dict[str, Any]:
275
+ """Run V5 benchmark."""
276
+ try:
277
+ results = []
278
+ total_natural_tokens = 0
279
+ total_v5_tokens = 0
280
+
281
+ for example in examples:
282
+ stats = self.parser.calculate_token_reduction(
283
+ example['natural'],
284
+ example['v5']
285
+ )
286
+ results.append(stats)
287
+ total_natural_tokens += stats['natural_tokens']
288
+ total_v5_tokens += stats['v5_tokens']
289
+
290
+ avg_reduction = round(
291
+ (1 - total_v5_tokens / total_natural_tokens) * 100, 1
292
+ ) if total_natural_tokens > 0 else 0
293
+
294
+ return {
295
+ "success": True,
296
+ "examples": results,
297
+ "aggregate": {
298
+ "total_natural_tokens": total_natural_tokens,
299
+ "total_v5_tokens": total_v5_tokens,
300
+ "total_saved": total_natural_tokens - total_v5_tokens,
301
+ "average_reduction_percent": avg_reduction
302
+ }
303
+ }
304
+ except Exception as e:
305
+ return {
306
+ "success": False,
307
+ "error": str(e)
308
+ }
309
+
310
+ async def start(self, transport: str = "stdio"):
311
+ """Start the MCP server.
312
+
313
+ Args:
314
+ transport: Transport type ("stdio", "sse", etc.)
315
+ """
316
+ await self.server.run(transport)
317
+
318
+
319
+ def create_server() -> CompTextMCPServer:
320
+ """Create and return a new CompText MCP server instance."""
321
+ return CompTextMCPServer()
322
+
323
+
324
+ # CLI entry point for MCP server
325
+ def main():
326
+ """Main entry point for MCP server."""
327
+ import asyncio
328
+
329
+ if not MCP_AVAILABLE:
330
+ print("Error: MCP package not installed")
331
+ print("Install with: pip install mcp")
332
+ sys.exit(1)
333
+
334
+ server = create_server()
335
+
336
+ print("CompText V5.0 ULTRA MCP Server")
337
+ print("Listening on stdio...")
338
+
339
+ asyncio.run(server.start("stdio"))
340
+
341
+
342
+ if __name__ == '__main__':
343
+ main()
@@ -0,0 +1,20 @@
1
+ """CompText Modules - Implementation of 13 production modules (A-M)."""
2
+
3
+ from .module_a import ModuleA
4
+ from .module_b import ModuleB
5
+ from .module_c import ModuleC
6
+ from .module_d import ModuleD
7
+ from .module_e import ModuleE
8
+ from .module_f import ModuleF
9
+ from .module_g import ModuleG
10
+ from .module_h import ModuleH
11
+ from .module_i import ModuleI
12
+ from .module_j import ModuleJ
13
+ from .module_k import ModuleK
14
+ from .module_l import ModuleL
15
+ from .module_m import ModuleM
16
+
17
+ __all__ = [
18
+ 'ModuleA', 'ModuleB', 'ModuleC', 'ModuleD', 'ModuleE', 'ModuleF',
19
+ 'ModuleG', 'ModuleH', 'ModuleI', 'ModuleJ', 'ModuleK', 'ModuleL', 'ModuleM'
20
+ ]
@@ -0,0 +1,33 @@
1
+ """Base module class for CompText modules.
2
+
3
+ Modules may optionally inherit from BaseModule (not required with the
4
+ decorator system), but it provides a convenient ``execute`` dispatcher.
5
+ """
6
+
7
+ from abc import ABC
8
+ from typing import Any, Dict, List
9
+
10
+
11
+ class BaseModule(ABC):
12
+ """Base class for all CompText modules.
13
+
14
+ With the new ``@codex_module`` / ``@codex_command`` decorator system,
15
+ subclassing BaseModule is optional. The class is kept for backward
16
+ compatibility and because the generic ``execute`` dispatcher is useful.
17
+ """
18
+
19
+ def get_commands(self) -> List[Dict[str, Any]]:
20
+ """Return command metadata from the registry decorators."""
21
+ from comptext_codex.registry import registry
22
+
23
+ meta = getattr(self.__class__, "_module_meta", None)
24
+ if meta is None:
25
+ return []
26
+ return [c.to_dict() for c in registry.get_commands_for_module(meta.code)]
27
+
28
+ def execute(self, cmd, context: Dict[str, Any]) -> Any:
29
+ handler_name = f"execute_{cmd.command.lower()}"
30
+ if hasattr(self, handler_name):
31
+ handler = getattr(self, handler_name)
32
+ return handler(*cmd.args, context=context, **cmd.kwargs)
33
+ raise NotImplementedError(f"Command {cmd.command} not implemented in {self.__class__.__name__}")