agent-apprenticeship 0.1.0 → 0.1.1
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.
|
@@ -34,20 +34,50 @@ function runCandidate(command, args) {
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function
|
|
37
|
+
function pythonCheck(command) {
|
|
38
38
|
const check = runCandidate(command, [
|
|
39
39
|
"-c",
|
|
40
40
|
"import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)"
|
|
41
41
|
]);
|
|
42
|
-
return
|
|
42
|
+
return {
|
|
43
|
+
usable: !check.error && check.status === 0,
|
|
44
|
+
error: check.error ? String(check.error.message || check.error) : null,
|
|
45
|
+
status: check.status
|
|
46
|
+
};
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
function findPython() {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
if (process.env.AA_PYTHON) {
|
|
51
|
+
const candidate = expandHome(process.env.AA_PYTHON);
|
|
52
|
+
const check = pythonCheck(candidate);
|
|
53
|
+
if (check.usable) return candidate;
|
|
54
|
+
console.error("AA_PYTHON is set but does not point to Python 3.11 or newer.");
|
|
55
|
+
console.error(`AA_PYTHON=${candidate}`);
|
|
56
|
+
console.error("");
|
|
57
|
+
console.error("Agent Apprenticeship requires Python 3.11 or newer.");
|
|
58
|
+
console.error("");
|
|
59
|
+
console.error("macOS Homebrew:");
|
|
60
|
+
console.error("brew install python@3.11");
|
|
61
|
+
console.error("");
|
|
62
|
+
console.error("Or set:");
|
|
63
|
+
console.error("AA_PYTHON=/path/to/python3.11");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const candidates = [
|
|
67
|
+
"python3.13",
|
|
68
|
+
"python3.12",
|
|
69
|
+
"python3.11",
|
|
70
|
+
"/opt/homebrew/bin/python3.13",
|
|
71
|
+
"/opt/homebrew/bin/python3.12",
|
|
72
|
+
"/opt/homebrew/bin/python3.11",
|
|
73
|
+
"/usr/local/bin/python3.13",
|
|
74
|
+
"/usr/local/bin/python3.12",
|
|
75
|
+
"/usr/local/bin/python3.11",
|
|
76
|
+
"python3",
|
|
77
|
+
"python"
|
|
78
|
+
];
|
|
49
79
|
for (const candidate of candidates) {
|
|
50
|
-
if (
|
|
80
|
+
if (pythonCheck(candidate).usable) return candidate;
|
|
51
81
|
}
|
|
52
82
|
return null;
|
|
53
83
|
}
|
|
@@ -120,7 +150,12 @@ function runCli(python, args, usePackagedSource) {
|
|
|
120
150
|
const python = findPython();
|
|
121
151
|
if (!python) {
|
|
122
152
|
console.error("Agent Apprenticeship requires Python 3.11 or newer.");
|
|
123
|
-
console.error("
|
|
153
|
+
console.error("");
|
|
154
|
+
console.error("macOS Homebrew:");
|
|
155
|
+
console.error("brew install python@3.11");
|
|
156
|
+
console.error("");
|
|
157
|
+
console.error("Or set:");
|
|
158
|
+
console.error("AA_PYTHON=/path/to/python3.11");
|
|
124
159
|
process.exit(1);
|
|
125
160
|
}
|
|
126
161
|
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agent-apprenticeship"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "Open framework for turning real agent work into transferable agent experience"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Agent Apprenticeship framework."""
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.1"
|
|
@@ -289,7 +289,7 @@ def _configure_detected_model_provider(row: dict) -> None:
|
|
|
289
289
|
)
|
|
290
290
|
|
|
291
291
|
|
|
292
|
-
def _first_run_setup(*, interactive: bool) -> None:
|
|
292
|
+
def _first_run_setup(*, interactive: bool, defaults: bool=False) -> None:
|
|
293
293
|
detected_agents = _detect_apprentice_agents()
|
|
294
294
|
typer.echo("")
|
|
295
295
|
if detected_agents:
|
|
@@ -298,7 +298,10 @@ def _first_run_setup(*, interactive: bool) -> None:
|
|
|
298
298
|
typer.echo(f"{idx}. {row['display_name']} - command found ({row['command']})")
|
|
299
299
|
custom_index = len(detected_agents) + 1
|
|
300
300
|
typer.echo(f"{custom_index}. Custom - use a custom command template")
|
|
301
|
-
if
|
|
301
|
+
if defaults:
|
|
302
|
+
_configure_detected_apprentice_agent(detected_agents[0])
|
|
303
|
+
typer.echo(f"Configured Apprentice Agent: {detected_agents[0]['display_name']}")
|
|
304
|
+
elif interactive:
|
|
302
305
|
choice = _choose_detected_index(custom_index, default=1)
|
|
303
306
|
if choice and choice <= len(detected_agents):
|
|
304
307
|
_configure_detected_apprentice_agent(detected_agents[choice - 1])
|
|
@@ -318,7 +321,10 @@ def _first_run_setup(*, interactive: bool) -> None:
|
|
|
318
321
|
typer.echo("Detected Mentor Model Provider keys:")
|
|
319
322
|
for idx, row in enumerate(detected_providers, 1):
|
|
320
323
|
typer.echo(f"{idx}. {row['display_name']} - {row['api_key_env_var']} visible")
|
|
321
|
-
if
|
|
324
|
+
if defaults:
|
|
325
|
+
_configure_detected_model_provider(detected_providers[0])
|
|
326
|
+
typer.echo(f"Configured Mentor Model Provider: {detected_providers[0]['display_name']}")
|
|
327
|
+
elif interactive:
|
|
322
328
|
choice = _choose_detected_index(len(detected_providers), default=1)
|
|
323
329
|
if choice:
|
|
324
330
|
_configure_detected_model_provider(detected_providers[choice - 1])
|
|
@@ -641,10 +647,13 @@ def _ensure_apprentice_agent_ready(settings, runner: str | None=None, interactiv
|
|
|
641
647
|
def init(
|
|
642
648
|
overwrite: bool=typer.Option(False, help='Replace existing settings.json with defaults.'),
|
|
643
649
|
setup: bool=typer.Option(False, '--setup', help='Detect installed Apprentice Agents and Mentor Model Provider keys.'),
|
|
650
|
+
defaults: bool=typer.Option(False, '--defaults', '--non-interactive', help='Initialize with deterministic defaults and never prompt.'),
|
|
644
651
|
):
|
|
645
652
|
path=init_settings(overwrite=overwrite)
|
|
646
653
|
typer.echo(f'initialized Agent Apprenticeship settings at {path}')
|
|
647
|
-
if
|
|
654
|
+
if defaults:
|
|
655
|
+
_first_run_setup(interactive=False, defaults=True)
|
|
656
|
+
elif setup or sys.stdin.isatty():
|
|
648
657
|
_first_run_setup(interactive=bool(setup or sys.stdin.isatty()))
|
|
649
658
|
|
|
650
659
|
@app.command('settings')
|
|
@@ -2812,27 +2821,27 @@ def bundle_contribute(path: Path=typer.Argument(..., help='Contribution Bundle f
|
|
|
2812
2821
|
typer.echo('View files:')
|
|
2813
2822
|
typer.echo(f'open {path}')
|
|
2814
2823
|
|
|
2815
|
-
@app.command('init-env')
|
|
2824
|
+
@app.command('init-env', hidden=True)
|
|
2816
2825
|
def init_env():
|
|
2817
2826
|
dst=Path('.env.local')
|
|
2818
2827
|
if not dst.exists(): shutil.copyfile('.env.example', dst); typer.echo('created .env.local from .env.example')
|
|
2819
2828
|
else: typer.echo('.env.local already exists')
|
|
2820
2829
|
|
|
2821
|
-
@app.command('run-task')
|
|
2830
|
+
@app.command('run-task', hidden=True)
|
|
2822
2831
|
def run_task(input: Path=typer.Option(Path('data/seed_tasks/hard_finance_reconciliation.jsonl')), output_root: Path=Path('outputs'), runner: str='deterministic'):
|
|
2823
2832
|
raw=RawTaskRecord.model_validate(read_jsonl(input)[0])
|
|
2824
2833
|
run_root=output_root/'runs'/'single'
|
|
2825
2834
|
pkg=run_one(raw, run_root, runner=runner); typer.echo(str(pkg))
|
|
2826
2835
|
|
|
2827
|
-
@app.command('run-batch')
|
|
2836
|
+
@app.command('run-batch', hidden=True)
|
|
2828
2837
|
def run_batch(input: Path=typer.Option(...), limit: int|None=None, resume: bool=False, max_parallel: int=1, retry_limit: int=0, task_timeout_seconds: int=900, runner: str='deterministic', release_id: str|None=None, output_root: Path=Path('outputs'), max_iterations: int|None=None):
|
|
2829
2838
|
typer.echo(str(run_batch_impl(input, output_root, limit, resume, max_parallel, retry_limit, task_timeout_seconds, runner, release_id, max_iterations=max_iterations)))
|
|
2830
2839
|
|
|
2831
|
-
@app.command('run-many')
|
|
2840
|
+
@app.command('run-many', hidden=True)
|
|
2832
2841
|
def run_many(input: Path=typer.Option(...), limit: int|None=None, resume: bool=False, max_parallel: int=1, retry_limit: int=0, task_timeout_seconds: int=900, runner: str='deterministic', release_id: str|None=None, output_root: Path=Path('outputs'), max_iterations: int|None=None):
|
|
2833
2842
|
typer.echo(str(run_batch_impl(input, output_root, limit, resume, max_parallel, retry_limit, task_timeout_seconds, runner, release_id, max_iterations=max_iterations)))
|
|
2834
2843
|
|
|
2835
|
-
@app.command('create-bundle')
|
|
2844
|
+
@app.command('create-bundle', hidden=True)
|
|
2836
2845
|
def create_bundle(
|
|
2837
2846
|
run_root: Path=typer.Option(...),
|
|
2838
2847
|
bundle_root: Path|None=typer.Option(None),
|
|
@@ -2841,15 +2850,15 @@ def create_bundle(
|
|
|
2841
2850
|
):
|
|
2842
2851
|
typer.echo(str(create_contribution_bundle(run_root, bundle_root, include_debug=include_debug, release_style=release_style)))
|
|
2843
2852
|
|
|
2844
|
-
@app.command('create-release')
|
|
2853
|
+
@app.command('create-release', hidden=True)
|
|
2845
2854
|
def create_release(run_root: Path=typer.Option(Path('outputs/runs/single')), release_root: Path=typer.Option(Path('outputs/releases/manual'))):
|
|
2846
2855
|
typer.echo(str(create_release_impl(run_root, release_root)))
|
|
2847
2856
|
|
|
2848
|
-
@app.command('validate-release')
|
|
2857
|
+
@app.command('validate-release', hidden=True)
|
|
2849
2858
|
def validate_release(release_root: Path=typer.Option(...)):
|
|
2850
2859
|
c=validate_release_impl(release_root); typer.echo(format_counters(c)); raise typer.Exit(0 if c['release_valid'] else 1)
|
|
2851
2860
|
|
|
2852
|
-
@app.command('validate-public-release')
|
|
2861
|
+
@app.command('validate-public-release', hidden=True)
|
|
2853
2862
|
def validate_public_release(release_root: Path=typer.Option(...)):
|
|
2854
2863
|
public=release_root/'public' if (release_root/'public').exists() else release_root
|
|
2855
2864
|
c=validate_release_impl(release_root if (release_root/'public').exists() else release_root.parent) if public.name == 'public' else validate_release_impl(release_root)
|
|
@@ -2857,7 +2866,7 @@ def validate_public_release(release_root: Path=typer.Option(...)):
|
|
|
2857
2866
|
raise typer.Exit(0 if c.get('public_release_valid') else 1)
|
|
2858
2867
|
|
|
2859
2868
|
|
|
2860
|
-
@app.command('repair-roles')
|
|
2869
|
+
@app.command('repair-roles', hidden=True)
|
|
2861
2870
|
def repair_roles(run_root: Path=typer.Option(...), task_id: str=typer.Option(...), roles: str=typer.Option('evaluator_agent,grader_agent,verifier_agent'), attempts: str=typer.Option('baseline,revised'), rebuild_release: Path|None=typer.Option(None)):
|
|
2862
2871
|
"""Re-run model evaluation roles from existing task package artifacts/traces."""
|
|
2863
2872
|
from .schemas import RubricSpec, ActualOutputs, AgentTrace, GraderResult, VerifierResult
|
|
@@ -2916,7 +2925,7 @@ def repair_roles(run_root: Path=typer.Option(...), task_id: str=typer.Option(...
|
|
|
2916
2925
|
typer.echo(f'rebuilt release={rebuild_release}')
|
|
2917
2926
|
|
|
2918
2927
|
|
|
2919
|
-
@app.command('summarize-releases')
|
|
2928
|
+
@app.command('summarize-releases', hidden=True)
|
|
2920
2929
|
def summarize_releases(release_root: Path=typer.Option(Path('outputs/releases')), pattern: str=typer.Option('tasks-*')):
|
|
2921
2930
|
"""Summarize release readiness across a release directory."""
|
|
2922
2931
|
from .validation import validate_release
|
|
@@ -2952,17 +2961,17 @@ def summarize_releases(release_root: Path=typer.Option(Path('outputs/releases'))
|
|
|
2952
2961
|
typer.echo('task_ids_publishable_with_warnings=' + ','.join(warnings))
|
|
2953
2962
|
typer.echo('task_ids_clean_publishable=' + ','.join(clean))
|
|
2954
2963
|
|
|
2955
|
-
@app.command('inspect-trace')
|
|
2964
|
+
@app.command('inspect-trace', hidden=True)
|
|
2956
2965
|
def inspect_trace(trace_path: Path):
|
|
2957
2966
|
t=AgentTrace.model_validate_json(trace_path.read_text()); typer.echo(f'trace_id={t.trace_id}\ntask_id={t.task_id}\nsteps={len(t.steps)}')
|
|
2958
2967
|
|
|
2959
|
-
@app.command('codex-smoke')
|
|
2968
|
+
@app.command('codex-smoke', hidden=True)
|
|
2960
2969
|
def codex_smoke():
|
|
2961
2970
|
if not shutil.which('codex'):
|
|
2962
2971
|
typer.echo('codex_available=false'); raise typer.Exit(1)
|
|
2963
2972
|
typer.echo('codex_available=true')
|
|
2964
2973
|
|
|
2965
|
-
@app.command('llm-smoke')
|
|
2974
|
+
@app.command('llm-smoke', hidden=True)
|
|
2966
2975
|
def llm_smoke(
|
|
2967
2976
|
output_dir: Path=Path('outputs/llm_smoke'),
|
|
2968
2977
|
provider: str | None=typer.Option(None, '--provider', help='Mentor Model Provider id to test. Defaults to configured provider.'),
|