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.
- package/bin/algo-extract.js +54 -85
- package/bin/algo-verify.js +0 -1
- package/bin/install.js +1 -1
- package/package.json +2 -2
- package/src/cli/cli_entry.py +16 -15
- package/src/cli/commands.py +24 -2
package/bin/algo-extract.js
CHANGED
|
@@ -3,131 +3,100 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* AlgoMath Extract Command
|
|
5
5
|
*
|
|
6
|
-
* Extract algorithm from
|
|
7
|
-
* Usage:
|
|
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
|
|
27
|
-
.
|
|
28
|
-
.option('-n, --name <name>', '
|
|
29
|
-
.option('
|
|
30
|
-
.
|
|
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('║
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
});
|
|
56
|
+
python.stdout.on('data', (data) => {
|
|
57
|
+
output += data.toString();
|
|
58
|
+
});
|
|
93
59
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
cwd: path.join(__dirname, '..')
|
|
98
|
-
});
|
|
60
|
+
python.stderr.on('data', (data) => {
|
|
61
|
+
error += data.toString();
|
|
62
|
+
});
|
|
99
63
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
108
|
-
error += data.toString();
|
|
109
|
-
});
|
|
73
|
+
spinner.succeed('Extraction complete!');
|
|
110
74
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
}
|
package/bin/algo-verify.js
CHANGED
package/bin/install.js
CHANGED
|
@@ -73,7 +73,7 @@ console.log(GREEN + `
|
|
|
73
73
|
██╔══██║██║ ██║ ██║██║ ██║██║╚██╔╝██║██╔══██║ ██║ ██╔══██║
|
|
74
74
|
██║ ██║███████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║
|
|
75
75
|
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
76
|
-
Framework Installer v1.0.
|
|
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.
|
|
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": "^
|
|
44
|
+
"inquirer": "^8.2.6",
|
|
45
45
|
"chalk": "^4.1.2",
|
|
46
46
|
"ora": "^5.4.1"
|
|
47
47
|
},
|
package/src/cli/cli_entry.py
CHANGED
|
@@ -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',
|
package/src/cli/commands.py
CHANGED
|
@@ -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
|
|