algomath-extract 1.0.15 → 1.0.17

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.
@@ -3,131 +3,100 @@
3
3
  /**
4
4
  * AlgoMath Extract Command
5
5
  *
6
- * Extract algorithm from mathematical text using interactive prompts
7
- * Usage: /algo-extract
8
- *
9
- * This command will:
10
- * 1. Prompt user for mathematical text (or accept from clipboard/file)
11
- * 2. Extract structured algorithm steps
12
- * 3. Save to context
6
+ * Extract algorithm from PDF/text file
7
+ * Usage: algoextract <file-path> [--name <name>]
13
8
  */
14
9
 
15
10
  const { Command } = require('commander');
16
- const inquirer = require('inquirer');
17
11
  const chalk = require('chalk');
18
12
  const ora = require('ora');
19
- const { spawn } = require('child_process');
20
13
  const path = require('path');
21
14
 
22
15
  const program = new Command();
23
16
 
24
17
  program
25
18
  .name('algo-extract')
26
- .description('Extract algorithm from mathematical text')
27
- .option('-t, --text <text>', 'Mathematical text describing the algorithm')
28
- .option('-n, --name <name>', 'Optional name for the algorithm')
29
- .option('-f, --file <file>', 'Read text from file')
30
- .option('--clipboard', 'Read text from clipboard')
31
- .action(async (options) => {
19
+ .description('Extract algorithm from PDF or text file')
20
+ .argument('<file>', 'Path to PDF or text file')
21
+ .option('-n, --name <name>', 'Algorithm name (optional)')
22
+ .option('--auto', 'Skip interactive prompts')
23
+ .action(async (file, options) => {
32
24
  console.log(chalk.blue.bold('╔════════════════════════════════════════╗'));
33
- console.log(chalk.blue.bold('║ AlgoMath - Extract Algorithm ║'));
25
+ console.log(chalk.blue.bold('║ AlgoMath - Extract Algorithm ║'));
34
26
  console.log(chalk.blue.bold('╚════════════════════════════════════════╝'));
35
27
  console.log();
36
28
 
37
29
  try {
38
- let text = options.text;
39
- let name = options.name;
40
-
41
- // If no text provided, prompt interactively
42
- if (!text && !options.file && !options.clipboard) {
43
- const answers = await inquirer.prompt([
44
- {
45
- type: 'editor',
46
- name: 'text',
47
- message: 'Paste the mathematical text describing the algorithm:',
48
- validate: (input) => input.trim().length > 0 || 'Text is required'
49
- },
50
- {
51
- type: 'input',
52
- name: 'name',
53
- message: 'Algorithm name (optional):',
54
- default: ''
55
- }
56
- ]);
57
- text = answers.text;
58
- name = answers.name || null;
59
- } else if (options.file) {
60
- const fs = require('fs');
61
- text = fs.readFileSync(options.file, 'utf8');
62
- }
63
-
64
- // Validate we have text
65
- if (!text || text.trim().length === 0) {
66
- console.error(chalk.red('Error: No text provided'));
30
+ // Validate file exists
31
+ const fs = require('fs');
32
+ if (!fs.existsSync(file)) {
33
+ console.error(chalk.red(`✗ File not found: ${file}`));
67
34
  process.exit(1);
68
35
  }
69
36
 
37
+ console.log(chalk.green(`✓ Reading file: ${file}`));
38
+
70
39
  // Show extraction progress
71
- const spinner = ora('Extracting algorithm...').start();
40
+ const spinner = ora('Extracting algorithm from file...').start();
72
41
 
73
42
  // Call Python extraction
43
+ const { spawn } = require('child_process');
74
44
  const pythonScript = path.join(__dirname, '..', 'src', 'cli', 'cli_entry.py');
75
- const pythonArgs = ['extract', text];
76
- if (name) {
77
- pythonArgs.push('--name', name);
45
+
46
+ const pythonArgs = ['extract', '--file', file];
47
+ if (options.name) {
48
+ pythonArgs.push('--name', options.name);
78
49
  }
79
50
 
80
- const result = await runPython(pythonScript, pythonArgs);
81
-
82
- spinner.succeed('Extraction complete!');
83
-
84
- // Parse and display results
85
- const output = JSON.parse(result);
86
- displayResult(output);
51
+ const result = await new Promise((resolve, reject) => {
52
+ const python = spawn('python3', [pythonScript, ...pythonArgs]);
53
+ let output = '';
54
+ let error = '';
87
55
 
88
- } catch (error) {
89
- console.error(chalk.red('Error:'), error.message);
90
- process.exit(1);
91
- }
92
- });
56
+ python.stdout.on('data', (data) => {
57
+ output += data.toString();
58
+ });
93
59
 
94
- function runPython(script, args) {
95
- return new Promise((resolve, reject) => {
96
- const python = spawn('python3', [script, ...args], {
97
- cwd: path.join(__dirname, '..')
98
- });
60
+ python.stderr.on('data', (data) => {
61
+ error += data.toString();
62
+ });
99
63
 
100
- let output = '';
101
- let error = '';
102
-
103
- python.stdout.on('data', (data) => {
104
- output += data.toString();
105
- });
64
+ python.on('close', (code) => {
65
+ if (code !== 0) {
66
+ reject(new Error(error || `Python process exited with code ${code}`));
67
+ } else {
68
+ resolve(output);
69
+ }
70
+ });
71
+ });
106
72
 
107
- python.stderr.on('data', (data) => {
108
- error += data.toString();
109
- });
73
+ spinner.succeed('Extraction complete!');
110
74
 
111
- python.on('close', (code) => {
112
- if (code !== 0) {
113
- reject(new Error(error || `Python process exited with code ${code}`));
114
- } else {
115
- resolve(output);
75
+ // Parse and display results
76
+ try {
77
+ const output = JSON.parse(result);
78
+ displayResult(output);
79
+ } catch (e) {
80
+ // If not JSON, just display the output
81
+ console.log('\n' + result);
116
82
  }
117
- });
83
+
84
+ } catch (error) {
85
+ console.error(chalk.red('\n✗ Error:'), error.message);
86
+ process.exit(1);
87
+ }
118
88
  });
119
- }
120
89
 
121
90
  function displayResult(output) {
122
91
  console.log();
123
92
  console.log(chalk.green.bold('✓ Algorithm extracted successfully'));
124
93
  console.log();
125
-
94
+
126
95
  if (output.algorithm) {
127
96
  console.log(chalk.cyan('Algorithm:'), output.algorithm.name || '(unnamed)');
128
97
  console.log(chalk.cyan('Steps:'), output.algorithm.steps?.length || 0);
129
98
  console.log();
130
-
99
+
131
100
  if (output.next_steps) {
132
101
  console.log(chalk.gray('Next steps:'));
133
102
  output.next_steps.forEach(step => {
@@ -135,7 +104,7 @@ function displayResult(output) {
135
104
  });
136
105
  }
137
106
  }
138
-
107
+
139
108
  console.log();
140
109
  console.log(chalk.blue('Use /algo-generate to generate code from these steps'));
141
110
  }
@@ -8,7 +8,6 @@
8
8
  */
9
9
 
10
10
  const { Command } = require('commander');
11
- const inquirer = require('inquirer');
12
11
  const chalk = require('chalk');
13
12
  const ora = require('ora');
14
13
  const { spawn } = require('child_process');
package/bin/install.js CHANGED
@@ -73,7 +73,7 @@ console.log(GREEN + `
73
73
  ██╔══██║██║ ██║ ██║██║ ██║██║╚██╔╝██║██╔══██║ ██║ ██╔══██║
74
74
  ██║ ██║███████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║
75
75
  ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
76
- Framework Installer v1.0.15
76
+ Framework Installer v1.0.17
77
77
  Mathematical Algorithm Extraction & Code
78
78
  ` + RESET + '\n');
79
79
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "algomath-extract",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "AlgoMath Framework - Transform AI assistants into reliable mathematical problem-solving environments",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -41,7 +41,7 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "commander": "^11.0.0",
44
- "inquirer": "^9.2.0",
44
+ "inquirer": "^8.2.6",
45
45
  "chalk": "^4.1.2",
46
46
  "ora": "^5.4.1"
47
47
  },
@@ -30,44 +30,45 @@ def main():
30
30
  """Main entry point for CLI."""
31
31
  parser = argparse.ArgumentParser(description='AlgoMath CLI')
32
32
  subparsers = parser.add_subparsers(dest='command', help='Available commands')
33
-
33
+
34
34
  # Extract command
35
- extract_parser = subparsers.add_parser('extract', help='Extract algorithm from text')
36
- extract_parser.add_argument('text', help='Mathematical text')
35
+ extract_parser = subparsers.add_parser('extract', help='Extract algorithm from text or file')
36
+ extract_parser.add_argument('text', nargs='?', help='Mathematical text (optional if --file provided)')
37
+ extract_parser.add_argument('--file', '-f', help='Path to PDF or text file', default=None)
37
38
  extract_parser.add_argument('--name', '-n', help='Algorithm name', default=None)
38
-
39
+
39
40
  # Generate command
40
41
  generate_parser = subparsers.add_parser('generate', help='Generate code from steps')
41
-
42
+
42
43
  # Run command
43
44
  run_parser = subparsers.add_parser('run', help='Execute generated code')
44
45
  run_parser.add_argument('--skip', action='store_true', help='Skip execution')
45
-
46
+
46
47
  # Verify command
47
48
  verify_parser = subparsers.add_parser('verify', help='Verify execution results')
48
49
  verify_parser.add_argument('--step', type=int, help='Explain specific step')
49
50
  verify_parser.add_argument('--detailed', action='store_true', help='Show detailed explanation')
50
51
  verify_parser.add_argument('--diagnostic', action='store_true', help='Run diagnostic mode')
51
-
52
+
52
53
  # Status command
53
54
  status_parser = subparsers.add_parser('status', help='Show current state')
54
-
55
+
55
56
  # List command
56
57
  list_parser = subparsers.add_parser('list', help='List saved algorithms')
57
-
58
+
58
59
  # Help command
59
60
  help_parser = subparsers.add_parser('help', help='Show help')
60
-
61
+
61
62
  args = parser.parse_args()
62
-
63
+
63
64
  if not args.command:
64
65
  parser.print_help()
65
66
  sys.exit(1)
66
-
67
+
67
68
  try:
68
69
  # Route to appropriate command
69
70
  if args.command == 'extract':
70
- result = extract_command(args.text, args.name)
71
+ result = extract_command(text=args.text, file=args.file, name=args.name)
71
72
  elif args.command == 'generate':
72
73
  result = generate_command()
73
74
  elif args.command == 'run':
@@ -90,10 +91,10 @@ def main():
90
91
  'message': f'Unknown command: {args.command}'
91
92
  }))
92
93
  sys.exit(1)
93
-
94
+
94
95
  # Output result as JSON for Node.js to parse
95
96
  print(json.dumps(result))
96
-
97
+
97
98
  except Exception as e:
98
99
  print(json.dumps({
99
100
  'status': 'error',
@@ -22,18 +22,20 @@ from algomath.state import WorkflowState
22
22
  from src.workflows.run import run_execution
23
23
 
24
24
 
25
- def extract_command(text: str, name: Optional[str] = None) -> Dict[str, Any]:
25
+ def extract_command(text: Optional[str] = None, file: Optional[str] = None, name: Optional[str] = None) -> Dict[str, Any]:
26
26
  """
27
- Extract algorithm from mathematical text.
27
+ Extract algorithm from mathematical text or file.
28
28
 
29
29
  Args:
30
30
  text: Mathematical text describing an algorithm
31
+ file: Path to PDF or text file
31
32
  name: Optional name for the algorithm
32
33
 
33
34
  Returns:
34
35
  Dict with extraction status and results
35
36
  """
36
37
  from src.workflows.extract import extract_algorithm
38
+ from src.extraction.pdf_processor import PDFProcessor
37
39
 
38
40
  ctx = ContextManager()
39
41
  ctx.start_session()
@@ -41,6 +43,26 @@ def extract_command(text: str, name: Optional[str] = None) -> Dict[str, Any]:
41
43
  if name:
42
44
  ctx.create_algorithm(name)
43
45
 
46
+ # Handle file extraction
47
+ if file:
48
+ processor = PDFProcessor()
49
+ result = processor.extract_text(file)
50
+ if not result.success:
51
+ return {
52
+ 'status': 'error',
53
+ 'message': f"Failed to extract from file: {result.error}",
54
+ 'next_steps': ['Check file path', 'Try with text input instead']
55
+ }
56
+ text = result.text
57
+ print(f"Extracted {len(text)} characters from {result.file_type} file ({result.page_count} pages)")
58
+
59
+ if not text:
60
+ return {
61
+ 'status': 'error',
62
+ 'message': 'No text or file provided for extraction',
63
+ 'next_steps': ['Provide text directly', 'Use --file to specify a file path']
64
+ }
65
+
44
66
  result = extract_algorithm(ctx, text)
45
67
  return result
46
68