agent-apprenticeship 0.1.8 → 0.2.0
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/agent-apprenticeship.js +96 -22
- package/docs/bioactive_evidence_mapping_schema.md +113 -0
- package/docs/dataset_schema.md +160 -0
- package/docs/local_usage.md +191 -0
- package/docs/scaling_to_1000_tasks.md +3 -0
- package/docs/trace_schema.md +192 -0
- package/docs/v0.2_release_notes.md +61 -0
- package/package.json +2 -1
- package/pyproject.toml +1 -1
- package/src/agent_apprenticeship_trace/__init__.py +1 -1
- package/src/agent_apprenticeship_trace/bundle_exporter.py +36 -1
- package/src/agent_apprenticeship_trace/cli.py +73 -12
- package/src/agent_apprenticeship_trace/contract_verifier.py +686 -0
- package/src/agent_apprenticeship_trace/ecosystem_r2.py +2 -1
- package/src/agent_apprenticeship_trace/learning.py +203 -6
- package/src/agent_apprenticeship_trace/public_run.py +31 -3
- package/src/agent_apprenticeship_trace/public_sanitizer.py +3 -3
- package/src/agent_apprenticeship_trace/tdo.py +1323 -44
- package/src/agent_apprenticeship_trace/trace_normalizer.py +25 -2
- package/src/agent_apprenticeship_trace/version.py +15 -0
|
@@ -24,6 +24,7 @@ from .config import (
|
|
|
24
24
|
from .env import redact_secrets
|
|
25
25
|
from .io import append_jsonl, read_json, read_jsonl, write_json
|
|
26
26
|
from .public_sanitizer import sanitize_public_obj
|
|
27
|
+
from .version import get_package_version
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def utc_now() -> str:
|
|
@@ -236,7 +237,7 @@ def ecosystem_item_from_bundle(
|
|
|
236
237
|
str(metadata.get("economic_value_summary") or manifest.get("economic_value_summary") or "").strip()
|
|
237
238
|
or f"{expected_value.title()} reuse value based on trace evidence, artifact coverage, and generated training rows."
|
|
238
239
|
)
|
|
239
|
-
package_version = str(manifest.get("package_version") or manifest.get("agent_apprenticeship_version") or
|
|
240
|
+
package_version = str(manifest.get("package_version") or manifest.get("agent_apprenticeship_version") or get_package_version())
|
|
240
241
|
loop_count = int(loop_manifest.get("loop_iteration_count") or manifest.get("loop_iteration_count") or 0)
|
|
241
242
|
has_skill = (compiler_dir / "skill_pack").exists()
|
|
242
243
|
has_training = (compiler_dir / "training_time_package").exists()
|
|
@@ -12,6 +12,7 @@ from typing import Any
|
|
|
12
12
|
from .config import Settings, get_settings
|
|
13
13
|
from .env import contains_secret
|
|
14
14
|
from .io import append_jsonl, read_json, read_jsonl, write_json
|
|
15
|
+
from .version import get_package_version
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
PACK_STATUSES = {"draft", "active", "reverted", "removed"}
|
|
@@ -697,6 +698,7 @@ def install_runtime_training_from_bundle(
|
|
|
697
698
|
skill_md = skill_dir / "skill.md"
|
|
698
699
|
if not skill_md.exists():
|
|
699
700
|
raise FileNotFoundError(f"Runtime training skill.md not found in {bundle}")
|
|
701
|
+
quality = _runtime_training_quality(bundle)
|
|
700
702
|
package_id = str(_read_manifest_field(bundle, "bundle_id") or _read_manifest_field(bundle, "source_package_id") or bundle.name)
|
|
701
703
|
title = str(_read_manifest_field(bundle, "title") or _read_manifest_field(bundle, "source_task_id") or source_item_id)
|
|
702
704
|
digest = hashlib.sha256(f"{source_item_id}|{package_id}|{skill_md.read_text(errors='replace')[:5000]}".encode()).hexdigest()[:10]
|
|
@@ -761,6 +763,7 @@ def install_runtime_training_from_bundle(
|
|
|
761
763
|
"source_item_id": source_item_id,
|
|
762
764
|
"source_package_id": package_id,
|
|
763
765
|
"source_url": _read_manifest_field(bundle, "source_url"),
|
|
766
|
+
"package_version": get_package_version(),
|
|
764
767
|
"agent_target": agent_target,
|
|
765
768
|
"install_mode": "agent_apprenticeship_runtime",
|
|
766
769
|
"installed_at": utc_now(),
|
|
@@ -770,12 +773,80 @@ def install_runtime_training_from_bundle(
|
|
|
770
773
|
"backup_refs": [],
|
|
771
774
|
"reversible": True,
|
|
772
775
|
"generation_notes": ["native_agent_files_unchanged"],
|
|
776
|
+
"transfer_confidence": quality["transfer_confidence"],
|
|
777
|
+
"runtime_training_confidence": quality["transfer_confidence"],
|
|
778
|
+
"low_confidence_reasons": [quality["low_confidence_reason"]] if quality.get("low_confidence_reason") else [],
|
|
779
|
+
"source_quality_gate": quality,
|
|
773
780
|
}
|
|
774
781
|
write_json(target / "install_manifest.json", manifest)
|
|
775
782
|
append_jsonl(installed_skills_index_path(s), manifest)
|
|
776
783
|
return manifest
|
|
777
784
|
|
|
778
785
|
|
|
786
|
+
def _runtime_training_quality(bundle: Path) -> dict[str, Any]:
|
|
787
|
+
runtime = bundle / "experience_compiler" / "runtime_learning_package"
|
|
788
|
+
compiler = bundle / "experience_compiler"
|
|
789
|
+
has_actual = any((bundle / "attempts").glob("*/actual_outputs.json")) if (bundle / "attempts").exists() else False
|
|
790
|
+
has_artifacts = any((bundle / "attempts").glob("*/artifacts/*")) if (bundle / "attempts").exists() else False
|
|
791
|
+
required = {
|
|
792
|
+
"transfer_runbook": runtime / "transfer_runbook.md",
|
|
793
|
+
"minimal_prompt_context": runtime / "minimal_prompt_context.md",
|
|
794
|
+
"output_contract": runtime / "output_contract.json",
|
|
795
|
+
"artifact_contract": runtime / "artifact_contract.json",
|
|
796
|
+
"prefinal_verification_checklist": runtime / "prefinal_verification_checklist.json",
|
|
797
|
+
}
|
|
798
|
+
missing = [name for name, path in required.items() if not path.exists()]
|
|
799
|
+
evidence_map = compiler / "source_evidence_map.json"
|
|
800
|
+
source_score = _runtime_training_source_score(bundle)
|
|
801
|
+
checks = {
|
|
802
|
+
"actual_outputs_exist": has_actual,
|
|
803
|
+
"artifacts_exist": has_artifacts,
|
|
804
|
+
"source_evidence_map_exists": evidence_map.exists(),
|
|
805
|
+
"runtime_package_non_generic": bool((runtime / "transfer_runbook.md").exists() and len((runtime / "transfer_runbook.md").read_text(errors="replace")) > 500),
|
|
806
|
+
"required_runtime_contract_files_present": not missing,
|
|
807
|
+
"missing_runtime_contract_files": missing,
|
|
808
|
+
"source_score": source_score,
|
|
809
|
+
"source_score_passes_transfer_gate": source_score is None or source_score >= 0.7,
|
|
810
|
+
}
|
|
811
|
+
confidence = "high" if all(v for k, v in checks.items() if k != "missing_runtime_contract_files") else "low"
|
|
812
|
+
checks["transfer_confidence"] = confidence
|
|
813
|
+
reasons = list(missing)
|
|
814
|
+
if source_score is not None and source_score < 0.7:
|
|
815
|
+
reasons.append(f"source_score_below_transfer_gate:{source_score:.3f}")
|
|
816
|
+
checks["low_confidence_reason"] = "; ".join(reasons) if reasons else None
|
|
817
|
+
return checks
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
def _runtime_training_source_score(bundle: Path) -> float | None:
|
|
821
|
+
for rel in [
|
|
822
|
+
"grading/baseline_grader_result.json",
|
|
823
|
+
"evaluation/grader_result.json",
|
|
824
|
+
"evaluation/grader_results.json",
|
|
825
|
+
]:
|
|
826
|
+
path = bundle / rel
|
|
827
|
+
if not path.exists():
|
|
828
|
+
continue
|
|
829
|
+
try:
|
|
830
|
+
payload = read_json(path)
|
|
831
|
+
except Exception:
|
|
832
|
+
continue
|
|
833
|
+
if isinstance(payload, dict):
|
|
834
|
+
value = payload.get("score")
|
|
835
|
+
try:
|
|
836
|
+
return float(value)
|
|
837
|
+
except Exception:
|
|
838
|
+
pass
|
|
839
|
+
jsonl = bundle / "evaluation/grader_results.jsonl"
|
|
840
|
+
if jsonl.exists():
|
|
841
|
+
for row in read_jsonl(jsonl):
|
|
842
|
+
if isinstance(row, dict) and row.get("score") is not None:
|
|
843
|
+
try:
|
|
844
|
+
return float(row.get("score"))
|
|
845
|
+
except Exception:
|
|
846
|
+
continue
|
|
847
|
+
return None
|
|
848
|
+
|
|
849
|
+
|
|
779
850
|
def list_installed_skills(settings: Settings | None = None, include_disabled: bool = True) -> list[dict[str, Any]]:
|
|
780
851
|
root = installed_skills_root(settings)
|
|
781
852
|
rows: list[dict[str, Any]] = []
|
|
@@ -852,25 +923,45 @@ def select_runtime_training_for_run(
|
|
|
852
923
|
if not enabled:
|
|
853
924
|
return [], ""
|
|
854
925
|
query_terms = {token.lower() for token in re.findall(r"[A-Za-z][A-Za-z0-9_-]{2,}", instruction)}
|
|
855
|
-
scored: list[tuple[int, dict[str, Any]]] = []
|
|
926
|
+
scored: list[tuple[int, dict[str, Any], str]] = []
|
|
856
927
|
for skill in enabled:
|
|
857
928
|
overlap = len(query_terms & _skill_keywords(skill))
|
|
858
929
|
if force or overlap:
|
|
859
|
-
|
|
930
|
+
confidence = skill.get("transfer_confidence") or (skill.get("source_quality_gate") or {}).get("transfer_confidence") or "unknown"
|
|
931
|
+
source_gate = skill.get("source_quality_gate") if isinstance(skill.get("source_quality_gate"), dict) else {}
|
|
932
|
+
source_score = source_gate.get("source_score")
|
|
933
|
+
quality_penalty = 0
|
|
934
|
+
reason_bits = ["matched runtime training against the task request"]
|
|
935
|
+
if confidence == "low":
|
|
936
|
+
quality_penalty -= 50
|
|
937
|
+
reason_bits.append("low-confidence source; use cautiously")
|
|
938
|
+
if isinstance(source_score, (int, float)) and float(source_score) < 0.7:
|
|
939
|
+
quality_penalty -= 50
|
|
940
|
+
reason_bits.append(f"source score {float(source_score):.2f} below transfer gate")
|
|
941
|
+
if force:
|
|
942
|
+
reason_bits.append("explicit --use-installed-skills requested")
|
|
943
|
+
scored.append((overlap + quality_penalty, skill, "; ".join(reason_bits)))
|
|
860
944
|
scored.sort(key=lambda item: item[0], reverse=True)
|
|
861
|
-
selected = [skill for _, skill in scored[:limit]]
|
|
945
|
+
selected = [dict(skill, runtime_training_selection_reason=reason) for _, skill, reason in scored[:limit]]
|
|
862
946
|
if not selected:
|
|
863
947
|
return [], ""
|
|
864
948
|
sections = ["\n\n---\nInstalled Runtime Training\nUse these enabled skills only when they are relevant. The task instruction remains authoritative.\n"]
|
|
865
|
-
for skill in selected:
|
|
949
|
+
for idx, skill in enumerate(selected):
|
|
866
950
|
path = Path(str(skill.get("path")))
|
|
867
|
-
|
|
951
|
+
runtime_text, runtime_meta = _runtime_prompt_context(path)
|
|
952
|
+
skill = dict(skill)
|
|
953
|
+
skill.update(runtime_meta)
|
|
954
|
+
if runtime_text:
|
|
955
|
+
skill_text = runtime_text
|
|
956
|
+
else:
|
|
957
|
+
skill_text = (path / "skill.md").read_text(errors="replace") if (path / "skill.md").exists() else ""
|
|
868
958
|
sections.append(
|
|
869
959
|
f"\n## {skill.get('title') or skill.get('installed_skill_id')}\n"
|
|
870
960
|
f"installed_skill_id: {skill.get('installed_skill_id')}\n"
|
|
871
|
-
f"selection_reason: matched runtime training against the task request.\n\n"
|
|
961
|
+
f"selection_reason: {skill.get('runtime_training_selection_reason') or 'matched runtime training against the task request'}.\n\n"
|
|
872
962
|
f"{skill_text[:5000]}\n"
|
|
873
963
|
)
|
|
964
|
+
selected[idx] = skill
|
|
874
965
|
sections.append("---\n")
|
|
875
966
|
return selected, "\n".join(sections)
|
|
876
967
|
|
|
@@ -884,11 +975,117 @@ def installed_skill_run_refs(skills: list[dict[str, Any]]) -> list[dict[str, Any
|
|
|
884
975
|
"title": skill.get("title"),
|
|
885
976
|
"source_item_id": skill.get("source_item_id"),
|
|
886
977
|
"source_package_id": skill.get("source_package_id"),
|
|
978
|
+
"runtime_training_injected_sections": skill.get("runtime_training_injected_sections") or [],
|
|
979
|
+
"runtime_training_context_char_count": skill.get("runtime_training_context_char_count") or 0,
|
|
980
|
+
"runtime_training_content_hash": skill.get("runtime_training_content_hash"),
|
|
981
|
+
"runtime_training_selection_reason": skill.get("runtime_training_selection_reason"),
|
|
982
|
+
"transfer_confidence": skill.get("transfer_confidence"),
|
|
983
|
+
"runtime_training_confidence": skill.get("runtime_training_confidence") or skill.get("transfer_confidence"),
|
|
984
|
+
"low_confidence_reasons": skill.get("low_confidence_reasons") or [],
|
|
985
|
+
"source_quality_gate": skill.get("source_quality_gate"),
|
|
986
|
+
"selected_transfer_runbook_path": skill.get("selected_transfer_runbook_path"),
|
|
987
|
+
"selected_transfer_checklist_path": skill.get("selected_transfer_checklist_path"),
|
|
988
|
+
"injected_minimal_prompt_context": bool(skill.get("injected_minimal_prompt_context")),
|
|
989
|
+
"injected_output_contract": bool(skill.get("injected_output_contract")),
|
|
990
|
+
"injected_artifact_contract": bool(skill.get("injected_artifact_contract")),
|
|
991
|
+
"injected_prefinal_checklist": bool(skill.get("injected_prefinal_checklist")),
|
|
992
|
+
"prefinal_verification_passed": skill.get("prefinal_verification_passed"),
|
|
993
|
+
"repair_loop_count": skill.get("repair_loop_count", 0),
|
|
994
|
+
"contract_failures_json": skill.get("contract_failures_json") or [],
|
|
995
|
+
"runtime_training_injection_mode": skill.get("runtime_training_injection_mode"),
|
|
887
996
|
}
|
|
888
997
|
)
|
|
889
998
|
return refs
|
|
890
999
|
|
|
891
1000
|
|
|
1001
|
+
def _jsonl_preview(path: Path, limit: int = 8) -> str:
|
|
1002
|
+
if not path.exists() or not path.is_file():
|
|
1003
|
+
return ""
|
|
1004
|
+
lines: list[str] = []
|
|
1005
|
+
for line in path.read_text(errors="replace").splitlines():
|
|
1006
|
+
line = line.strip()
|
|
1007
|
+
if line:
|
|
1008
|
+
lines.append(line)
|
|
1009
|
+
if len(lines) >= limit:
|
|
1010
|
+
break
|
|
1011
|
+
return "\n".join(lines)
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
def _runtime_prompt_context(skill_root: Path) -> tuple[str, dict[str, Any]]:
|
|
1015
|
+
"""Return compact runtime-training context that is actually injected."""
|
|
1016
|
+
runtime = skill_root / "runtime_learning_package"
|
|
1017
|
+
injection_mode = (os.getenv("AA_RUNTIME_TRAINING_INJECTION_MODE") or "contract").strip().lower()
|
|
1018
|
+
if injection_mode == "full":
|
|
1019
|
+
ordered_files = [
|
|
1020
|
+
("minimal_prompt_context.md", "minimal_prompt_context"),
|
|
1021
|
+
("transfer_runbook.md", "transfer_runbook"),
|
|
1022
|
+
("transfer_checklist.json", "transfer_checklist"),
|
|
1023
|
+
("tool_execution_recipe.json", "tool_execution_recipe"),
|
|
1024
|
+
("output_verification_steps.jsonl", "output_verification_steps"),
|
|
1025
|
+
("common_errors_to_avoid.jsonl", "common_errors_to_avoid"),
|
|
1026
|
+
("runtime_instructions.md", "runtime_instructions"),
|
|
1027
|
+
]
|
|
1028
|
+
else:
|
|
1029
|
+
ordered_files = [
|
|
1030
|
+
("minimal_prompt_context.md", "minimal_prompt_context"),
|
|
1031
|
+
("output_contract.json", "output_contract"),
|
|
1032
|
+
("artifact_contract.json", "artifact_contract"),
|
|
1033
|
+
("prefinal_verification_checklist.json", "prefinal_verification_checklist"),
|
|
1034
|
+
]
|
|
1035
|
+
parts: list[str] = []
|
|
1036
|
+
injected_sections: list[str] = []
|
|
1037
|
+
selected_runbook = None
|
|
1038
|
+
selected_checklist = None
|
|
1039
|
+
for rel, section in ordered_files:
|
|
1040
|
+
path = runtime / rel
|
|
1041
|
+
if not path.exists() or not path.is_file():
|
|
1042
|
+
continue
|
|
1043
|
+
if rel.endswith(".jsonl"):
|
|
1044
|
+
text = _jsonl_preview(path)
|
|
1045
|
+
elif rel.endswith(".json"):
|
|
1046
|
+
try:
|
|
1047
|
+
payload = read_json(path)
|
|
1048
|
+
text = json.dumps(payload, indent=2, sort_keys=True)
|
|
1049
|
+
except Exception:
|
|
1050
|
+
text = path.read_text(errors="replace")
|
|
1051
|
+
else:
|
|
1052
|
+
text = path.read_text(errors="replace")
|
|
1053
|
+
text = text.strip()
|
|
1054
|
+
if not text:
|
|
1055
|
+
continue
|
|
1056
|
+
if rel == "transfer_runbook.md":
|
|
1057
|
+
selected_runbook = f"runtime_learning_package/{rel}"
|
|
1058
|
+
if rel == "transfer_checklist.json":
|
|
1059
|
+
selected_checklist = f"runtime_learning_package/{rel}"
|
|
1060
|
+
injected_sections.append(section)
|
|
1061
|
+
section_limit = 2200 if injection_mode == "full" else 950
|
|
1062
|
+
parts.append(f"### {section.replace('_', ' ').title()}\n{text[:section_limit]}")
|
|
1063
|
+
if selected_runbook is None and (runtime / "transfer_runbook.md").exists():
|
|
1064
|
+
selected_runbook = "runtime_learning_package/transfer_runbook.md"
|
|
1065
|
+
if selected_checklist is None:
|
|
1066
|
+
if (runtime / "prefinal_verification_checklist.json").exists():
|
|
1067
|
+
selected_checklist = "runtime_learning_package/prefinal_verification_checklist.json"
|
|
1068
|
+
elif (runtime / "transfer_checklist.json").exists():
|
|
1069
|
+
selected_checklist = "runtime_learning_package/transfer_checklist.json"
|
|
1070
|
+
combined = "\n\n".join(parts)
|
|
1071
|
+
digest = hashlib.sha256(combined.encode()).hexdigest()[:16] if combined else None
|
|
1072
|
+
return combined, {
|
|
1073
|
+
"runtime_training_injected_sections": injected_sections,
|
|
1074
|
+
"runtime_training_context_char_count": len(combined),
|
|
1075
|
+
"runtime_training_content_hash": digest,
|
|
1076
|
+
"selected_transfer_runbook_path": selected_runbook,
|
|
1077
|
+
"selected_transfer_checklist_path": selected_checklist,
|
|
1078
|
+
"injected_minimal_prompt_context": "minimal_prompt_context" in injected_sections,
|
|
1079
|
+
"injected_output_contract": "output_contract" in injected_sections,
|
|
1080
|
+
"injected_artifact_contract": "artifact_contract" in injected_sections,
|
|
1081
|
+
"injected_prefinal_checklist": "prefinal_verification_checklist" in injected_sections,
|
|
1082
|
+
"prefinal_verification_passed": None,
|
|
1083
|
+
"repair_loop_count": 0,
|
|
1084
|
+
"contract_failures_json": [],
|
|
1085
|
+
"runtime_training_injection_mode": injection_mode,
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
|
|
892
1089
|
def write_before_after_result(pack_path: Path, result: dict[str, Any]) -> Path:
|
|
893
1090
|
result = dict(result)
|
|
894
1091
|
result["created_at"] = utc_now()
|
|
@@ -52,7 +52,7 @@ def _write_failed_tdo_reports(run_root: Path, settings: Settings, error: str) ->
|
|
|
52
52
|
}
|
|
53
53
|
write_json(tdo_dir / "tdo_report.json", report)
|
|
54
54
|
write_json(tdo_dir / "tdo_manifest.json", {
|
|
55
|
-
"schema_version": "aa-
|
|
55
|
+
"schema_version": "aa-experience-compiler-v0.2",
|
|
56
56
|
"tdo_id": report["tdo_id"],
|
|
57
57
|
"tdo_status": "failed",
|
|
58
58
|
"source_package_id": pkg.name,
|
|
@@ -73,7 +73,7 @@ def _write_failed_tdo_reports(run_root: Path, settings: Settings, error: str) ->
|
|
|
73
73
|
"created_at": report["created_at"],
|
|
74
74
|
})
|
|
75
75
|
write_json(compiler_dir / "compiler_manifest.json", {
|
|
76
|
-
"schema_version": "aa-experience-compiler-v0.
|
|
76
|
+
"schema_version": "aa-experience-compiler-v0.2",
|
|
77
77
|
"compiler_status": "failed",
|
|
78
78
|
"source_package_id": pkg.name,
|
|
79
79
|
"compiler_output_refs": ["experience_compiler/compiler_report.json", "experience_compiler/compiler_manifest.json"],
|
|
@@ -994,11 +994,39 @@ def _runtime_training_session_fields(runtime_training_refs: list[dict] | None) -
|
|
|
994
994
|
"installed_skill_refs": [],
|
|
995
995
|
"installed_skill_ids": [],
|
|
996
996
|
}
|
|
997
|
+
injected_sections: list[str] = []
|
|
998
|
+
confidence_values: list[str] = []
|
|
999
|
+
selection_reasons: list[str] = []
|
|
1000
|
+
total_chars = 0
|
|
1001
|
+
content_hashes: list[str] = []
|
|
1002
|
+
for ref in refs:
|
|
1003
|
+
for section in ref.get("runtime_training_injected_sections") or []:
|
|
1004
|
+
if section not in injected_sections:
|
|
1005
|
+
injected_sections.append(section)
|
|
1006
|
+
source_gate = ref.get("source_quality_gate") if isinstance(ref.get("source_quality_gate"), dict) else {}
|
|
1007
|
+
confidence = ref.get("runtime_training_confidence") or ref.get("transfer_confidence") or source_gate.get("transfer_confidence")
|
|
1008
|
+
if confidence:
|
|
1009
|
+
confidence_values.append(str(confidence))
|
|
1010
|
+
reason = ref.get("runtime_training_selection_reason") or ref.get("selection_reason")
|
|
1011
|
+
if reason:
|
|
1012
|
+
selection_reasons.append(str(reason))
|
|
1013
|
+
total_chars += int(ref.get("runtime_training_context_char_count") or 0)
|
|
1014
|
+
if ref.get("runtime_training_content_hash"):
|
|
1015
|
+
content_hashes.append(str(ref.get("runtime_training_content_hash")))
|
|
997
1016
|
return {
|
|
998
1017
|
"runtime_training_used": True,
|
|
999
1018
|
"installed_skill_refs": refs,
|
|
1000
1019
|
"installed_skill_ids": [ref.get("installed_skill_id") for ref in refs if ref.get("installed_skill_id")],
|
|
1001
|
-
"runtime_training_selection_reason": "enabled installed runtime training matched this task or was explicitly requested",
|
|
1020
|
+
"runtime_training_selection_reason": "; ".join(selection_reasons) or "enabled installed runtime training matched this task or was explicitly requested",
|
|
1021
|
+
"runtime_training_confidence": "low" if "low" in confidence_values else "high" if confidence_values else "unknown",
|
|
1022
|
+
"runtime_training_injected_sections": injected_sections,
|
|
1023
|
+
"runtime_training_injected_char_count": total_chars,
|
|
1024
|
+
"runtime_training_content_hashes": content_hashes,
|
|
1025
|
+
"output_contract_used": "output_contract" in injected_sections,
|
|
1026
|
+
"artifact_contract_used": "artifact_contract" in injected_sections,
|
|
1027
|
+
"prefinal_verification_status": "not_run",
|
|
1028
|
+
"repair_loop_count": max((int(ref.get("repair_loop_count") or 0) for ref in refs), default=0),
|
|
1029
|
+
"contract_failures_json": [failure for ref in refs for failure in (ref.get("contract_failures_json") or [])],
|
|
1002
1030
|
}
|
|
1003
1031
|
|
|
1004
1032
|
|
|
@@ -56,9 +56,9 @@ PUBLIC_TEXT_REPLACEMENTS=[
|
|
|
56
56
|
("T" + "DO", "Experience Compiler"),
|
|
57
57
|
("Honest " + "limitations", "Generation notes"),
|
|
58
58
|
("honest " + "limitations", "generation notes"),
|
|
59
|
-
("
|
|
60
|
-
("
|
|
61
|
-
("
|
|
59
|
+
("Limit" + "ations", "Generation Notes"),
|
|
60
|
+
("limit" + "ations", "generation notes"),
|
|
61
|
+
("limit" + "ation", "generation note"),
|
|
62
62
|
("Applic" + "ability", "Best Use"),
|
|
63
63
|
("applic" + "ability", "fit"),
|
|
64
64
|
("Required " + "Conditions", "Required Inputs"),
|