vbagent 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {vbagent-0.2.0 → vbagent-0.2.1}/PKG-INFO +1 -1
- {vbagent-0.2.0 → vbagent-0.2.1}/pyproject.toml +1 -1
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/base.py +4 -1
- vbagent-0.2.1/vbagent/agents/classifier.py +68 -0
- vbagent-0.2.1/vbagent/agents/compile_fixer.py +57 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/scanner.py +38 -14
- vbagent-0.2.1/vbagent/cli/config.py +425 -0
- vbagent-0.2.1/vbagent/cli/init.py +248 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/main.py +15 -5
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/process.py +34 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/scan.py +27 -1
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/tikz.py +29 -1
- vbagent-0.2.1/vbagent/cli/util.py +327 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/variant.py +27 -0
- vbagent-0.2.1/vbagent/compile.py +444 -0
- vbagent-0.2.1/vbagent/config.py +665 -0
- vbagent-0.2.1/vbagent/prompts/classifier.py +65 -0
- vbagent-0.2.1/vbagent/prompts/scanner/__init__.py +136 -0
- vbagent-0.2.1/vbagent/prompts/subjects/__init__.py +328 -0
- vbagent-0.2.0/vbagent/agents/classifier.py +0 -39
- vbagent-0.2.0/vbagent/cli/config.py +0 -191
- vbagent-0.2.0/vbagent/config.py +0 -291
- vbagent-0.2.0/vbagent/prompts/classifier.py +0 -31
- vbagent-0.2.0/vbagent/prompts/scanner/__init__.py +0 -71
- {vbagent-0.2.0 → vbagent-0.2.1}/README.md +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/alternate.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/clarity_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/converter.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/grammar_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/idea.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/multi_variant.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/reviewer.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/selector.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/solution_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/tikz.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/tikz_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/agents/variant.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/alternate.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/batch.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/check.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/classify.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/common.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/convert.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/idea.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/cli/ref.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/batch.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/classification.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/diff.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/idea.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/pipeline.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/review.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/scan.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/models/version_store.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/alternate.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/clarity_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/converter.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/grammar_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/idea.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/reviewer.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/assertion_reason.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/common.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/match.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/mcq_mc.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/mcq_sc.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/passage.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/scanner/subjective.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/solution_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/tikz.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/tikz_checker.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/variants/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/variants/conceptual.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/variants/conceptual_calculus.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/variants/context.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/variants/multi_context.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/prompts/variants/numerical.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/references/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/references/context.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/references/store.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/references/tikz_store.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/templates/__init__.py +0 -0
- {vbagent-0.2.0 → vbagent-0.2.1}/vbagent/templates/agentic_context.py +0 -0
|
@@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Any, Optional
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from agents import Agent, ModelSettings
|
|
10
10
|
|
|
11
|
-
from vbagent.config import get_model, get_model_settings
|
|
11
|
+
from vbagent.config import get_model, get_model_settings, apply_provider_config
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def _get_agent_class():
|
|
@@ -115,6 +115,9 @@ def create_agent(
|
|
|
115
115
|
"""
|
|
116
116
|
Agent = _get_agent_class()
|
|
117
117
|
|
|
118
|
+
# Apply provider config (base_url, api_key) before creating agent
|
|
119
|
+
apply_provider_config()
|
|
120
|
+
|
|
118
121
|
# Get model and settings from config if not explicitly provided
|
|
119
122
|
if model is None:
|
|
120
123
|
model = get_model(agent_type or "default")
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Classifier agent for question image classification.
|
|
2
|
+
|
|
3
|
+
Uses openai-agents SDK to analyze question images and extract
|
|
4
|
+
structured metadata including question type, difficulty, topic, etc.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Optional
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from agents import Agent
|
|
11
|
+
|
|
12
|
+
from vbagent.agents.base import (
|
|
13
|
+
create_agent,
|
|
14
|
+
create_image_message,
|
|
15
|
+
run_agent_sync,
|
|
16
|
+
)
|
|
17
|
+
from vbagent.config import get_config
|
|
18
|
+
from vbagent.models.classification import ClassificationResult
|
|
19
|
+
from vbagent.prompts.classifier import get_classifier_prompt, get_user_template
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def create_classifier_agent(subject: Optional[str] = None) -> "Agent":
|
|
23
|
+
"""Create a classifier agent for a subject.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
subject: Subject override (uses config if not provided)
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Configured Agent instance for classification
|
|
30
|
+
"""
|
|
31
|
+
if subject is None:
|
|
32
|
+
subject = get_config().subject
|
|
33
|
+
|
|
34
|
+
prompt = get_classifier_prompt(subject)
|
|
35
|
+
|
|
36
|
+
return create_agent(
|
|
37
|
+
name=f"Classifier-{subject}",
|
|
38
|
+
instructions=prompt,
|
|
39
|
+
output_type=ClassificationResult,
|
|
40
|
+
agent_type="classifier",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Legacy: Create default classifier agent for backward compatibility
|
|
45
|
+
classifier_agent = create_classifier_agent("physics")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def classify(image_path: str, subject: Optional[str] = None) -> ClassificationResult:
|
|
49
|
+
"""Analyze a question image and return structured metadata.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
image_path: Path to the image file to classify
|
|
53
|
+
subject: Subject override (uses config if not provided)
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
ClassificationResult with extracted metadata
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
FileNotFoundError: If the image file doesn't exist
|
|
60
|
+
"""
|
|
61
|
+
if subject is None:
|
|
62
|
+
subject = get_config().subject
|
|
63
|
+
|
|
64
|
+
agent = create_classifier_agent(subject)
|
|
65
|
+
user_template = get_user_template(subject)
|
|
66
|
+
message = create_image_message(image_path, user_template)
|
|
67
|
+
result = run_agent_sync(agent, message)
|
|
68
|
+
return result
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Agent for fixing LaTeX compilation errors.
|
|
2
|
+
|
|
3
|
+
Takes a LaTeX snippet and pdflatex error output, returns corrected LaTeX.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from vbagent.agents.base import create_agent, run_agent_sync
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
SYSTEM_PROMPT = r"""You are a LaTeX error fixer. You receive LaTeX code that failed to compile and the pdflatex error output.
|
|
10
|
+
|
|
11
|
+
Your job:
|
|
12
|
+
1. Read the error messages carefully
|
|
13
|
+
2. Fix ONLY the errors — do not change the content or structure
|
|
14
|
+
3. Common fixes: missing braces, undefined commands, wrong environment names, missing $ delimiters
|
|
15
|
+
4. Output ONLY the corrected LaTeX code — no explanations, no markdown, no code blocks
|
|
16
|
+
|
|
17
|
+
CRITICAL: Output the EXACT same content with ONLY the compilation errors fixed. Do not add \documentclass, preamble, or any wrapping."""
|
|
18
|
+
|
|
19
|
+
USER_TEMPLATE = """Fix the compilation errors in this LaTeX code.
|
|
20
|
+
|
|
21
|
+
**Errors from pdflatex:**
|
|
22
|
+
```
|
|
23
|
+
{errors}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**LaTeX code to fix:**
|
|
27
|
+
```latex
|
|
28
|
+
{latex}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Output ONLY the corrected LaTeX code:"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def fix_latex(error_summary: str, latex: str) -> str:
|
|
35
|
+
"""Send LaTeX + errors to agent and get fixed version.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
error_summary: Parsed pdflatex error output
|
|
39
|
+
latex: The LaTeX code that failed to compile
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Corrected LaTeX code
|
|
43
|
+
"""
|
|
44
|
+
agent = create_agent(
|
|
45
|
+
name="LaTeX-Fixer",
|
|
46
|
+
instructions=SYSTEM_PROMPT,
|
|
47
|
+
agent_type="converter", # Use converter model (lighter/cheaper)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
prompt = USER_TEMPLATE.format(errors=error_summary, latex=latex)
|
|
51
|
+
result = run_agent_sync(agent, prompt)
|
|
52
|
+
|
|
53
|
+
# Clean markdown artifacts
|
|
54
|
+
import re
|
|
55
|
+
result = re.sub(r'^```(?:latex|tex)?\s*\n?', '', result, flags=re.IGNORECASE)
|
|
56
|
+
result = re.sub(r'\n?```\s*$', '', result)
|
|
57
|
+
return result.strip()
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"""Scanner agent for extracting LaTeX from
|
|
1
|
+
"""Scanner agent for extracting LaTeX from question images.
|
|
2
2
|
|
|
3
|
-
Uses openai-agents SDK to analyze
|
|
4
|
-
LaTeX code using type-specific prompts.
|
|
3
|
+
Uses openai-agents SDK to analyze question images and extract
|
|
4
|
+
LaTeX code using type-specific and subject-specific prompts.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import re
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING, Optional
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
11
|
from agents import Agent
|
|
@@ -15,9 +15,10 @@ from vbagent.agents.base import (
|
|
|
15
15
|
create_image_message,
|
|
16
16
|
run_agent_sync,
|
|
17
17
|
)
|
|
18
|
+
from vbagent.config import get_config
|
|
18
19
|
from vbagent.models.classification import ClassificationResult
|
|
19
20
|
from vbagent.models.scan import ScanResult
|
|
20
|
-
from vbagent.prompts.scanner import get_scanner_prompt,
|
|
21
|
+
from vbagent.prompts.scanner import get_scanner_prompt, get_user_template
|
|
21
22
|
from vbagent.references.context import get_context_prompt_section
|
|
22
23
|
|
|
23
24
|
|
|
@@ -51,17 +52,26 @@ def clean_latex_output(latex: str) -> str:
|
|
|
51
52
|
return latex.strip()
|
|
52
53
|
|
|
53
54
|
|
|
54
|
-
def create_scanner_agent(
|
|
55
|
+
def create_scanner_agent(
|
|
56
|
+
question_type: str,
|
|
57
|
+
use_context: bool = True,
|
|
58
|
+
subject: Optional[str] = None,
|
|
59
|
+
) -> "Agent":
|
|
55
60
|
"""Create a scanner agent with type-specific prompt.
|
|
56
61
|
|
|
57
62
|
Args:
|
|
58
63
|
question_type: The type of question (mcq_sc, mcq_mc, etc.)
|
|
59
64
|
use_context: Whether to include reference context in prompt
|
|
65
|
+
subject: Subject override (uses config if not provided)
|
|
60
66
|
|
|
61
67
|
Returns:
|
|
62
68
|
Configured Agent instance for scanning that question type
|
|
63
69
|
"""
|
|
64
|
-
|
|
70
|
+
# Get subject from config if not provided
|
|
71
|
+
if subject is None:
|
|
72
|
+
subject = get_config().subject
|
|
73
|
+
|
|
74
|
+
prompt = get_scanner_prompt(question_type, subject)
|
|
65
75
|
|
|
66
76
|
# Add reference context if enabled
|
|
67
77
|
context = get_context_prompt_section("latex", use_context)
|
|
@@ -69,7 +79,7 @@ def create_scanner_agent(question_type: str, use_context: bool = True) -> "Agent
|
|
|
69
79
|
prompt = prompt + "\n" + context
|
|
70
80
|
|
|
71
81
|
return create_agent(
|
|
72
|
-
name=f"Scanner-{question_type}",
|
|
82
|
+
name=f"Scanner-{question_type}-{subject}",
|
|
73
83
|
instructions=prompt,
|
|
74
84
|
agent_type="scanner",
|
|
75
85
|
)
|
|
@@ -79,8 +89,9 @@ def scan(
|
|
|
79
89
|
image_path: str,
|
|
80
90
|
classification: ClassificationResult,
|
|
81
91
|
use_context: bool = True,
|
|
92
|
+
subject: Optional[str] = None,
|
|
82
93
|
) -> ScanResult:
|
|
83
|
-
"""Extract LaTeX from a
|
|
94
|
+
"""Extract LaTeX from a question image.
|
|
84
95
|
|
|
85
96
|
Uses the classification result to select the appropriate prompt
|
|
86
97
|
for the question type.
|
|
@@ -89,6 +100,7 @@ def scan(
|
|
|
89
100
|
image_path: Path to the image file to scan
|
|
90
101
|
classification: Classification result with question type info
|
|
91
102
|
use_context: Whether to include reference context in prompt
|
|
103
|
+
subject: Subject override (uses config if not provided)
|
|
92
104
|
|
|
93
105
|
Returns:
|
|
94
106
|
ScanResult with extracted LaTeX and diagram info
|
|
@@ -96,8 +108,13 @@ def scan(
|
|
|
96
108
|
Raises:
|
|
97
109
|
FileNotFoundError: If the image file doesn't exist
|
|
98
110
|
"""
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
# Get subject from config if not provided
|
|
112
|
+
if subject is None:
|
|
113
|
+
subject = get_config().subject
|
|
114
|
+
|
|
115
|
+
agent = create_scanner_agent(classification.question_type, use_context, subject)
|
|
116
|
+
user_template = get_user_template(subject)
|
|
117
|
+
message = create_image_message(image_path, user_template)
|
|
101
118
|
raw_latex = run_agent_sync(agent, message)
|
|
102
119
|
|
|
103
120
|
# Clean up markdown artifacts from LLM output
|
|
@@ -114,8 +131,9 @@ def scan_with_type(
|
|
|
114
131
|
image_path: str,
|
|
115
132
|
question_type: str,
|
|
116
133
|
use_context: bool = True,
|
|
134
|
+
subject: Optional[str] = None,
|
|
117
135
|
) -> ScanResult:
|
|
118
|
-
"""Extract LaTeX from a
|
|
136
|
+
"""Extract LaTeX from a question image with explicit type.
|
|
119
137
|
|
|
120
138
|
Bypasses classification and uses the provided question type directly.
|
|
121
139
|
|
|
@@ -123,6 +141,7 @@ def scan_with_type(
|
|
|
123
141
|
image_path: Path to the image file to scan
|
|
124
142
|
question_type: The type of question (mcq_sc, mcq_mc, etc.)
|
|
125
143
|
use_context: Whether to include reference context in prompt
|
|
144
|
+
subject: Subject override (uses config if not provided)
|
|
126
145
|
|
|
127
146
|
Returns:
|
|
128
147
|
ScanResult with extracted LaTeX
|
|
@@ -130,8 +149,13 @@ def scan_with_type(
|
|
|
130
149
|
Raises:
|
|
131
150
|
FileNotFoundError: If the image file doesn't exist
|
|
132
151
|
"""
|
|
133
|
-
|
|
134
|
-
|
|
152
|
+
# Get subject from config if not provided
|
|
153
|
+
if subject is None:
|
|
154
|
+
subject = get_config().subject
|
|
155
|
+
|
|
156
|
+
agent = create_scanner_agent(question_type, use_context, subject)
|
|
157
|
+
user_template = get_user_template(subject)
|
|
158
|
+
message = create_image_message(image_path, user_template)
|
|
135
159
|
raw_latex = run_agent_sync(agent, message)
|
|
136
160
|
|
|
137
161
|
# Clean up markdown artifacts from LLM output
|