agent-apprenticeship 0.1.9 → 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/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 +1322 -43
- package/src/agent_apprenticeship_trace/trace_normalizer.py +25 -2
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Agent Apprenticeship Trace Schema
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Agent Apprenticeship traces record authentic task work so completed workflows can become reusable agent experience. AgentTrace records observable workflow steps: task state, Apprentice Agent action, observed environment response, next state, artifacts produced, and evidence used by mentors, evaluators, verifiers, and graders.
|
|
6
|
+
|
|
7
|
+
Official quality labels come from mentor, expert, evaluator, verifier, and grader records, not from Apprentice Agent self-evaluation. This separation keeps the raw trace focused on what happened while outcome labels remain grounded in external evidence.
|
|
8
|
+
|
|
9
|
+
## Public Product Model
|
|
10
|
+
|
|
11
|
+
Public task metadata uses `apprenticeship_mode`:
|
|
12
|
+
|
|
13
|
+
- `autonomous` for Autonomous Apprenticeship
|
|
14
|
+
- `expert_led` for Expert-Led Apprenticeship
|
|
15
|
+
- `org_custom` for Organization Custom
|
|
16
|
+
|
|
17
|
+
The older internal `mentor_mode` field may remain in legacy packages for compatibility, but public docs and new package metadata should prefer `apprenticeship_mode`. Mentor Model Providers, experts, evaluators, verifiers, and graders remain outcome evidence sources. Apprentice Agent self-assessment is not outcome truth.
|
|
18
|
+
|
|
19
|
+
## Authentic Workflow Tracing
|
|
20
|
+
|
|
21
|
+
Trace real task work only. Do not trace Agent Apprenticeship packaging, public upload mechanics, or ecosystem storage steps as task work. Keep one meaningful action per step. Do not compress multiple actions into a vague paragraph. Preserve causality through `caused_by`, `causal_type`, and `causal_note`.
|
|
22
|
+
|
|
23
|
+
## Canonical Outputs
|
|
24
|
+
|
|
25
|
+
`actual_outputs.json` is the canonical output contract. Traces should include `actual_outputs_ref` when known, plus `artifact_refs`, `deliverable_refs`, `files_created`, `output_summary`, and `final_output_summary` derived from actual outputs rather than copied raw deliverables.
|
|
26
|
+
|
|
27
|
+
Large files, screenshots, PDFs, tables, logs, audio, video, workbooks, and binary artifacts must be referenced through package-relative artifact refs. Do not embed huge binaries in JSON.
|
|
28
|
+
|
|
29
|
+
## Observation, Input, Output, State Change
|
|
30
|
+
|
|
31
|
+
`observation` records what the agent saw before acting. `input` records the exact command, tool request, user instruction, artifact, or feedback used. `output` records the observed tool/environment response. `state_change` records what changed after the action.
|
|
32
|
+
|
|
33
|
+
## Step Core Fields
|
|
34
|
+
|
|
35
|
+
Meaningful non-user steps should populate:
|
|
36
|
+
|
|
37
|
+
- `step`, `turn`, `actor`, `action`
|
|
38
|
+
- `operation`, `tool`
|
|
39
|
+
- `observation`, `input`, `output`, `state_change`
|
|
40
|
+
- `reasoning`
|
|
41
|
+
- `caused_by`, `causal_type`, `causal_note`
|
|
42
|
+
- `success`, `step_outcome`
|
|
43
|
+
- `artifact_refs` when evidence or outputs are created, read, or validated
|
|
44
|
+
|
|
45
|
+
## Conditional Fields
|
|
46
|
+
|
|
47
|
+
Populate conditional fields when the event calls for them:
|
|
48
|
+
|
|
49
|
+
- `input_source` when input comes from the user, a prior step, a tool result, an artifact, mentor feedback, verifier feedback, expert feedback, a follow-up, or retry context.
|
|
50
|
+
- `feedback_type` and `feedback_content` when the step records feedback, correction, approval, clarification, revision guidance, or follow-up instructions.
|
|
51
|
+
- `retry_of` when a step repairs or revises a prior step.
|
|
52
|
+
- `alternatives_considered` for meaningful strategy, tool, remediation, or design choices.
|
|
53
|
+
- `execution_mode` defaults to `serial`; use `parallel` and `parallel_group` only for real fanout work.
|
|
54
|
+
- `started_at` and `ended_at` only when measured by runtime.
|
|
55
|
+
|
|
56
|
+
## Environment Domain Taxonomy And Interaction Surface Taxonomy
|
|
57
|
+
|
|
58
|
+
Every meaningful operation should identify its direct interface with `interaction_surface`, broader category with `environment_domain`, and a subtype with `surface_type` when useful.
|
|
59
|
+
|
|
60
|
+
Supported surfaces:
|
|
61
|
+
|
|
62
|
+
- `api`
|
|
63
|
+
- `mcp_tool`, `mcp_resource`, `mcp_prompt`
|
|
64
|
+
- `browser`, `computer_use`
|
|
65
|
+
- `cli`, `file`, `codebase`
|
|
66
|
+
- `database`
|
|
67
|
+
- `spreadsheet`, `table`
|
|
68
|
+
- `search`
|
|
69
|
+
- `cloud_console`, `saas_app`
|
|
70
|
+
- `async_job`, `queue`, `webhook`, `scheduler`
|
|
71
|
+
- `messaging`, `email`, `collaboration`
|
|
72
|
+
- `document`, `pdf`
|
|
73
|
+
- `multimodal`
|
|
74
|
+
- `device`, `industrial`, `physical`
|
|
75
|
+
- `mixed`, `other_tool`, `other_surface`, `unknown`
|
|
76
|
+
|
|
77
|
+
If a workflow crosses systems, use `environment_domain = mixed`, record `connected_surfaces`, split actions by system, and preserve `cross_system_dependencies`, `handoff_refs`, `state_sync_refs`, `consistency_checks`, and `system_of_record`.
|
|
78
|
+
|
|
79
|
+
## Surface-Specific Evidence
|
|
80
|
+
|
|
81
|
+
When an operation clearly uses a surface, do not leave the relevant fields silently empty. If data is unavailable, set `surface_capture_status`, `surface_capture_notes`, and `missing_surface_fields`.
|
|
82
|
+
|
|
83
|
+
API steps should capture endpoint, method, version, status, request/response refs, resource IDs, auth mode without secrets, pagination, rate limits, retries, and errors.
|
|
84
|
+
|
|
85
|
+
MCP steps should capture server, capability type, tool/resource/prompt name, argument refs, result refs, schemas, call IDs, and errors.
|
|
86
|
+
|
|
87
|
+
Database steps should capture database type, schema/table, query type, query ref or hash, row counts, affected rows, transaction IDs, snapshots, explain plans, rollback refs, and errors.
|
|
88
|
+
|
|
89
|
+
Spreadsheet and table steps should capture workbook refs, sheet names, ranges, row/column counts, formula refs, pivots, charts, validation refs, before/after refs, and diffs.
|
|
90
|
+
|
|
91
|
+
CLI, file, and codebase steps should capture command, cwd ref, exit code, stdout/stderr refs, file operations, paths, diffs, patches, git state, test/build/lint refs, process IDs, and timeouts.
|
|
92
|
+
|
|
93
|
+
Search steps should capture query, provider, scope, filters, result count, selected result refs, citation refs, ranking signals, time range, and errors.
|
|
94
|
+
|
|
95
|
+
Browser, computer-use, and software steps should capture UI surface, app name/version, OS, device, window/page title, URL or resource ID, visible-state refs, screenshot refs, DOM/accessibility refs, selectors, coordinates, action type, input text, before/after refs, network/API refs, and software state refs.
|
|
96
|
+
|
|
97
|
+
Cloud, SaaS, and enterprise app steps should capture service, workspace/project/tenant identifiers when safe, resource or ticket IDs, object state refs, permission context, region, environment, deployment IDs, audit logs, and change-request refs.
|
|
98
|
+
|
|
99
|
+
Async, queue, webhook, and scheduler steps should capture job/message/webhook/schedule IDs, trigger type, enqueue/start/completion times, retry count, delivery/polling/callback status, result refs, and dead-letter refs.
|
|
100
|
+
|
|
101
|
+
Messaging, email, and collaboration steps should capture platform, channel/thread/message IDs, sender/recipient roles, message refs, attachment refs, decisions, approval state, and follow-up requirements.
|
|
102
|
+
|
|
103
|
+
Document, PDF, report, and extraction steps should capture document refs, document type, page/section refs, text/OCR/table/figure/citation/annotation refs, summaries, and document diffs.
|
|
104
|
+
|
|
105
|
+
Device, industrial, and physical workflow steps should capture physical environment type, device details when safe, sensor/telemetry refs, actuator command summaries, control mode, before/after physical state refs, calibration refs, safety state, safety limits, operator override, human supervision, simulation or real-world status, latency, tolerance, rollback action, emergency stop, and compliance refs.
|
|
106
|
+
|
|
107
|
+
## Multi-Agent And Multimodal Support
|
|
108
|
+
|
|
109
|
+
Multi-agent workflows should preserve `actor_kind`, `actor_role`, `agent_id`, `agent_name`, `subagent_id`, `subagent_name`, `subagent_role`, `parent_agent_id`, `delegation_id`, `delegation_source_step`, `handoff_reason`, `handoff_payload_ref`, `handoff_output_refs`, `subagent_output_refs`, `coordination_pattern`, `communication_channel`, and `depends_on_agent_outputs`.
|
|
110
|
+
|
|
111
|
+
Multimodal workflows should preserve `modality`, `modalities`, `media_type`, `mime_type`, `artifact_role`, `artifact_hash`, `artifact_preview_ref`, `ocr_text_ref`, `transcript_ref`, `annotation_ref`, `bbox_refs`, `frame_refs`, `timecode_refs`, `table_refs`, `sheet_refs`, and `derived_text_summary`.
|
|
112
|
+
|
|
113
|
+
## Completeness Warnings
|
|
114
|
+
|
|
115
|
+
New traces should record warnings, not fabricate missing values:
|
|
116
|
+
|
|
117
|
+
- `surface_capture_status = complete | partial | unavailable | not_applicable`
|
|
118
|
+
- `surface_capture_notes`
|
|
119
|
+
- `missing_surface_fields`
|
|
120
|
+
- `trace_quality_warnings`
|
|
121
|
+
|
|
122
|
+
Old seed traces remain compatible when these fields are absent.
|
|
123
|
+
|
|
124
|
+
## Loop Review Packets
|
|
125
|
+
|
|
126
|
+
Each new iterative workflow loop should create review artifacts after an Apprentice Agent iteration and before model or expert review. The package-level structure is:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
loops/
|
|
130
|
+
loop_manifest.json
|
|
131
|
+
iterations/
|
|
132
|
+
001/
|
|
133
|
+
review_packet.md
|
|
134
|
+
review_packet.json
|
|
135
|
+
output_snapshot.json
|
|
136
|
+
artifact_index.json
|
|
137
|
+
trace_refs.json
|
|
138
|
+
rubric_status.json
|
|
139
|
+
verifier_status.json
|
|
140
|
+
evaluator_feedback.json
|
|
141
|
+
reviewer_feedback.json
|
|
142
|
+
revision_plan.json
|
|
143
|
+
diff_report.json
|
|
144
|
+
loop_decision.json
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`review_packet.json` is the current iteration dossier. It should include `loop_id`, `loop_iteration`, mode, task/package/run ids, the current goal, output refs, `actual_outputs_ref`, artifact refs and previews, trace refs, key trace steps, rubric and verifier status, evaluator status, known failures, missing outputs, open questions, surface/environment summaries, previous iteration refs, diff from the previous iteration, reviewer instructions, recommended review focus, stop/continue options, and `created_at`.
|
|
148
|
+
|
|
149
|
+
Autonomous model review should use the review packet as the review source before judging the attempt. Expert-Led review should show or link the packet before collecting expert feedback. Review feedback records should say whether the reviewer was `mentor_model_provider`, `human_expert`, `org_custom_reviewer`, or `simulated_for_test`; simulated or auto-test checkpoints must not be presented as real human review.
|
|
150
|
+
|
|
151
|
+
Revision plans should cite feedback refs, list issues to fix, artifacts and outputs to update, verification steps, stop conditions, and creation time. The next iteration should record feedback refs used, changes made, changed artifacts/outputs, and whether feedback was applied. Record-only follow-ups may create a follow-up review update without inventing new execution data.
|
|
152
|
+
|
|
153
|
+
## Experience Compiler Use
|
|
154
|
+
|
|
155
|
+
The Experience Compiler runs after completed task work and follow-ups. It derives reusable runtime learning and training-time data from package evidence: task packets, rubrics, traces, `actual_outputs.json`, artifacts, attempt manifests, evaluator feedback, grader results, verifier results, revision plans, process supervision, reward modeling, revision preference pairs, lessons, follow-up records, mentor checkpoints, loop review packets, reviewer feedback, loop decisions, and diff reports.
|
|
156
|
+
|
|
157
|
+
The compiler emits:
|
|
158
|
+
|
|
159
|
+
- Experience Pack material
|
|
160
|
+
- Skill Pack material, including `skill_pack/skill.md`
|
|
161
|
+
- Runtime Learning Package material
|
|
162
|
+
- Training-Time Package material
|
|
163
|
+
- eval, verifier, reward, and preference rows
|
|
164
|
+
- observed environment-response rows
|
|
165
|
+
- surface event rows
|
|
166
|
+
- `environment_spec.json`
|
|
167
|
+
- reports and transfer-readiness records
|
|
168
|
+
|
|
169
|
+
It does not claim model training happened. It produces training-ready and runtime-ready material grounded in observed workflow evidence.
|
|
170
|
+
|
|
171
|
+
## World-Model-Ready Fields
|
|
172
|
+
|
|
173
|
+
World-model-ready fields include `environment_domain`, `interaction_surface`, `state_before`, `agent_action`, `observed_environment_response`, `state_after`, `turn_idx`, `total_turns`, and environment-response quality scores.
|
|
174
|
+
|
|
175
|
+
## World-Model-Ready Observed Rows
|
|
176
|
+
|
|
177
|
+
Observed environment-response rows should include state/action/next-state style data:
|
|
178
|
+
|
|
179
|
+
- `environment_domain`
|
|
180
|
+
- `interaction_surface`
|
|
181
|
+
- `state_before`
|
|
182
|
+
- `agent_action`
|
|
183
|
+
- `observed_environment_response`
|
|
184
|
+
- `state_after`
|
|
185
|
+
- `turn_idx`, `total_turns`
|
|
186
|
+
- `format_score`, `factuality_score`, `consistency_score`, `realism_score`, `training_quality_score`, `environment_response_quality_score`
|
|
187
|
+
|
|
188
|
+
These rows are saved as `environment_response_pairs.jsonl` in Experience Compiler outputs. `environment_spec.json` describes replay and environment readiness. No simulated environment responses are part of the product flow. There is no Qwen-AgentWorld runtime or simulator config in the product flow, and traces must not emit `simulated_environment_response`.
|
|
189
|
+
|
|
190
|
+
## Not Included
|
|
191
|
+
|
|
192
|
+
Do not add commerce metadata, public ranking language, or Apprentice Agent self-eval as outcome truth. Do not include secrets, API keys, auth headers, cookies, private local paths, `.env`, `.env.local`, source scrape internals, or huge binaries in JSON.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Agent Apprenticeship v0.2.0 Technical Release Notes
|
|
2
|
+
|
|
3
|
+
Agent Apprenticeship v0.2.0 expands the Experience Compilation system from Runtime Training reuse into a fuller package for agent training, evaluation, replay, verifier/reward work, and provenance audit.
|
|
4
|
+
|
|
5
|
+
## Core Product Changes
|
|
6
|
+
|
|
7
|
+
- Full Experience Compilation packages now include traces, attempts, artifacts, actual outputs, loop review packets, evaluation/verifier/grader records, Runtime Training, training-time packages, eval packages, environment/replay packages, manifests, and source evidence maps where available.
|
|
8
|
+
- Public Ecosystem mode defaults to automatic upload of the full Experience Compilation after completed tasks.
|
|
9
|
+
- Private Internal Only mode records a no-upload path and does not upload completed tasks.
|
|
10
|
+
- Ecosystem consumption is centered on two actions: Export Full Experience Compilation and Install Runtime Training.
|
|
11
|
+
- Runtime Training install/use records installed skill refs, selected Runtime Training refs, confidence metadata, injected sections, and compact contract-focused context.
|
|
12
|
+
- `apprentice bundle check` accepts local Experience Compilation folders that use task/package/compiler manifests, including regenerated seed task packages.
|
|
13
|
+
|
|
14
|
+
## Experience Compiler And Training Packages
|
|
15
|
+
|
|
16
|
+
- Experience Compiler outputs now include stronger package metadata, schema versions, compiler versions, package versions from `get_package_version()`, row counts, public/private mode, and provenance fields.
|
|
17
|
+
- Generated package material is no longer treated as only prompt/completion data. The package supports SFT and LoRA-ready instruction rows, process supervision, reward model rows, verifier model rows, preference pairs, critique/revision pairs, failure cases, task variants, eval/rubric rows, environment/replay rows, and agentic rollout material.
|
|
18
|
+
- Source evidence maps now include stable evidence IDs, evidence types, visibility, confidence, content hashes where available, row evidence links, and validation for broken refs.
|
|
19
|
+
- Eval and environment packages now have first-class manifests and replay/scoring-oriented metadata.
|
|
20
|
+
|
|
21
|
+
## Demo B Local Proof
|
|
22
|
+
|
|
23
|
+
Demo B is a local ALE workflow-family mirrored transfer proof, not an official ALE benchmark score.
|
|
24
|
+
|
|
25
|
+
- Completed workflow families: 7
|
|
26
|
+
- Improved: 7
|
|
27
|
+
- Same: 0
|
|
28
|
+
- Worse: 0
|
|
29
|
+
- Severe regressions: 0
|
|
30
|
+
- Average baseline score: 0.3429
|
|
31
|
+
- Average treatment score: 0.8929
|
|
32
|
+
- Average delta: +0.5500
|
|
33
|
+
- Median delta: +0.4500
|
|
34
|
+
- Leakage check: passed
|
|
35
|
+
|
|
36
|
+
The supported claim is that Agent Apprenticeship Runtime Training from source Experience Compilations improved related held-out mirrored workflow-family tasks in this local proof set.
|
|
37
|
+
|
|
38
|
+
## Seed Dataset v0.2
|
|
39
|
+
|
|
40
|
+
Seed Dataset v0.2 is an Experience Compilation dataset generated from seed tasks. It is not the specialized bioactive/wellness model-training dataset.
|
|
41
|
+
|
|
42
|
+
- Full Experience Compilations: 505
|
|
43
|
+
- Skill packs: 505
|
|
44
|
+
- Runtime Training packages: 505
|
|
45
|
+
- Training-time packages: 505
|
|
46
|
+
- Eval packages: 505
|
|
47
|
+
- Environment/replay packages: 505
|
|
48
|
+
- Source evidence maps: 505
|
|
49
|
+
- Source evidence rows: 6,483
|
|
50
|
+
- Row evidence links: 15,004
|
|
51
|
+
- Viewer/export configs: 15
|
|
52
|
+
- Normalized Data Viewer rows: 39,835
|
|
53
|
+
|
|
54
|
+
Use the wording “505 Experience Compilations plus 39,835 normalized Data Viewer rows.” Do not describe the normalized viewer rows as tasks.
|
|
55
|
+
|
|
56
|
+
## Release Boundary
|
|
57
|
+
|
|
58
|
+
- The package version is 0.2.0 for release-candidate builds.
|
|
59
|
+
- The regenerated Seed Dataset v0.2 was generated before npm v0.2.0 publication and records the local package metadata present at generation time.
|
|
60
|
+
- No model weights are included.
|
|
61
|
+
- No official ALE benchmark score is claimed for the mirrored transfer tasks.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-apprenticeship",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "The living ecosystem for AI agents learning from real-world work through iterative loops and training-signal exchange.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"README.md",
|
|
16
16
|
"LICENSE",
|
|
17
|
+
"docs",
|
|
17
18
|
"pyproject.toml",
|
|
18
19
|
"src/agent_apprenticeship_trace",
|
|
19
20
|
"bin"
|
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.
|
|
7
|
+
version = "0.2.0"
|
|
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.
|
|
2
|
+
__version__ = "0.2.0"
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import shutil
|
|
4
4
|
import tempfile
|
|
5
5
|
import re
|
|
6
|
+
from datetime import datetime, timezone
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
@@ -12,6 +13,7 @@ from .public_sanitizer import sanitize_public_obj, sanitize_public_text
|
|
|
12
13
|
from .release_exporter import create_release
|
|
13
14
|
from .tdo import tdo_manifest_fields_from_report
|
|
14
15
|
from .loop_review import summarize_loop_reviews
|
|
16
|
+
from .version import get_package_version
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def _count_jsonl(path: Path) -> int:
|
|
@@ -87,8 +89,12 @@ def _run_status(release_root: Path) -> str:
|
|
|
87
89
|
|
|
88
90
|
|
|
89
91
|
def contribution_counts(release_root: Path) -> dict[str, int]:
|
|
92
|
+
trace_count = _count_jsonl(release_root / "agent_traces.jsonl")
|
|
93
|
+
actual_outputs_count = _count_jsonl(release_root / "actual_outputs.jsonl")
|
|
90
94
|
return {
|
|
91
|
-
"attempts":
|
|
95
|
+
"attempts": actual_outputs_count,
|
|
96
|
+
"actual_outputs_count": actual_outputs_count,
|
|
97
|
+
"trace_count": trace_count,
|
|
92
98
|
"traced_steps": _trace_step_count(release_root / "agent_traces.jsonl"),
|
|
93
99
|
"process_supervision_rows": _count_jsonl(release_root / "process_supervision.jsonl"),
|
|
94
100
|
"reward_modeling_rows": _count_jsonl(release_root / "reward_modeling.jsonl"),
|
|
@@ -310,16 +316,31 @@ def _bundle_metadata_shape(bundle_root: Path, release_root: Path, settings: Sett
|
|
|
310
316
|
role = task.get("agent_apprentice_role") or task.get("apprenticeship_role")
|
|
311
317
|
metadata = {
|
|
312
318
|
"bundle_id": f"aa-bundle-{_slug(run_id)}",
|
|
319
|
+
"experience_compilation_id": f"aa-compilation-{_slug(run_id)}",
|
|
320
|
+
"compilation_id": f"aa-compilation-{_slug(run_id)}",
|
|
321
|
+
"schema_version": "aa-experience-compilation-v0.2",
|
|
322
|
+
"package_version": get_package_version(),
|
|
323
|
+
"created_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
313
324
|
"title": title,
|
|
325
|
+
"task_title": title,
|
|
314
326
|
**counts,
|
|
315
327
|
"domains": _list_value(task.get("domain")),
|
|
316
328
|
"subdomains": _list_value(task.get("subdomain")),
|
|
329
|
+
"domain": (_list_value(task.get("domain")) or ["general"])[0],
|
|
330
|
+
"subdomain": (_list_value(task.get("subdomain")) or ["general"])[0],
|
|
331
|
+
"workflow_family": task.get("task_family") or task.get("workflow_family") or task.get("workflow_type") or "general_workflow",
|
|
332
|
+
"tags": sorted(set([str(task.get("domain") or "general"), str(task.get("subdomain") or "general"), str(task.get("workflow_type") or "workflow")]))[:12],
|
|
333
|
+
"surfaces": [],
|
|
334
|
+
"tools": [],
|
|
317
335
|
"agent_apprentice_role": role,
|
|
318
336
|
"expected_economic_value": task.get("expected_economic_value"),
|
|
319
337
|
"expected_economic_value_for_agent_apprentice": task.get("expected_economic_value_for_agent_apprentice"),
|
|
320
338
|
"apprenticeship_mode": _session_apprenticeship_mode(session, settings),
|
|
321
339
|
"apprenticeship_mode_display": apprenticeship_mode_display(_session_apprenticeship_mode(session, settings)),
|
|
322
340
|
"mentor_mode": _session_mentor_mode(session, settings),
|
|
341
|
+
"public_private_mode": getattr(settings, "contribution_mode", None),
|
|
342
|
+
"sharing_upload_mode": getattr(settings, "contribution_mode", None),
|
|
343
|
+
"private_internal_no_upload_confirmed": getattr(settings, "contribution_mode", None) == "private_internal",
|
|
323
344
|
"task_status": task_status,
|
|
324
345
|
"run_status": run_status,
|
|
325
346
|
}
|
|
@@ -391,7 +412,14 @@ def _tdo_manifest_shape(release_root: Path) -> dict[str, Any]:
|
|
|
391
412
|
def _experience_compiler_manifest_shape(release_root: Path, latest_report: dict[str, Any]) -> dict[str, Any]:
|
|
392
413
|
compiler_dirs = sorted(path for path in (release_root / "packages").glob("*/experience_compiler") if path.is_dir())
|
|
393
414
|
refs: list[str] = []
|
|
415
|
+
compiler_manifest: dict[str, Any] = {}
|
|
416
|
+
source_evidence_coverage: dict[str, Any] = {}
|
|
417
|
+
quality_report: dict[str, Any] = {}
|
|
394
418
|
if len(compiler_dirs) == 1:
|
|
419
|
+
compiler_manifest = read_json(compiler_dirs[0] / "compiler_manifest.json") if (compiler_dirs[0] / "compiler_manifest.json").exists() else {}
|
|
420
|
+
source_map = read_json(compiler_dirs[0] / "source_evidence_map.json") if (compiler_dirs[0] / "source_evidence_map.json").exists() else {}
|
|
421
|
+
source_evidence_coverage = source_map.get("coverage_statistics") or {}
|
|
422
|
+
quality_report = read_json(compiler_dirs[0] / "quality_report.json") if (compiler_dirs[0] / "quality_report.json").exists() else {}
|
|
395
423
|
for child in sorted(compiler_dirs[0].rglob("*")):
|
|
396
424
|
if child.is_file():
|
|
397
425
|
refs.append(f"experience_compiler/{child.relative_to(compiler_dirs[0]).as_posix()}")
|
|
@@ -406,10 +434,17 @@ def _experience_compiler_manifest_shape(release_root: Path, latest_report: dict[
|
|
|
406
434
|
"experience_compiler_id": str(latest_report.get("tdo_id") or "").replace("tdo_", "compiler_", 1),
|
|
407
435
|
"experience_compiler_output_refs": refs,
|
|
408
436
|
"experience_compiler_rows_by_type": latest_report.get("rows_accepted_by_type") or {},
|
|
437
|
+
"training_row_counts": latest_report.get("rows_accepted_by_type") or {},
|
|
438
|
+
"training_row_counts_by_file": compiler_manifest.get("training_row_counts_by_file") or quality_report.get("training_row_counts_by_file") or {},
|
|
439
|
+
"source_evidence_map_count": source_evidence_coverage.get("evidence_ref_count"),
|
|
440
|
+
"source_evidence_row_link_count": source_evidence_coverage.get("row_link_count"),
|
|
409
441
|
"experience_compiler_rounds_run": latest_report.get("rounds_run"),
|
|
410
442
|
"experience_compiler_average_quality_score": latest_report.get("average_quality_score"),
|
|
411
443
|
"experience_compiler_average_reuse_value_score": latest_report.get("average_reuse_value_score"),
|
|
412
444
|
"experience_compiler_judge_source": latest_report.get("tdo_judge_source"),
|
|
445
|
+
"compiler_version": compiler_manifest.get("compiler_version"),
|
|
446
|
+
"training_row_schema_version": compiler_manifest.get("training_row_schema_version"),
|
|
447
|
+
"source_evidence_map_schema_version": compiler_manifest.get("source_evidence_map_schema_version"),
|
|
413
448
|
}
|
|
414
449
|
|
|
415
450
|
|
|
@@ -152,6 +152,12 @@ def _print_public_ecosystem_contribution_help(bundle: str | Path) -> None:
|
|
|
152
152
|
typer.echo('Forsy ecosystem')
|
|
153
153
|
|
|
154
154
|
|
|
155
|
+
def _print_private_internal_share_note(bundle: str | Path) -> None:
|
|
156
|
+
typer.echo('Private Internal Only: no Public Ecosystem upload was made.')
|
|
157
|
+
typer.echo('Optional manual share:')
|
|
158
|
+
typer.echo(f'apprentice ecosystem contribute {bundle}')
|
|
159
|
+
|
|
160
|
+
|
|
155
161
|
def _print_first_run_banner() -> None:
|
|
156
162
|
typer.echo(FIRST_RUN_BANNER)
|
|
157
163
|
typer.echo("")
|
|
@@ -199,7 +205,7 @@ def _print_task_result(
|
|
|
199
205
|
mode = get_settings().training_contribution_mode
|
|
200
206
|
typer.echo(f'Agent Training Contribution Mode: {training_contribution_mode_display(mode)}')
|
|
201
207
|
if mode == "private_internal_only":
|
|
202
|
-
|
|
208
|
+
_print_private_internal_share_note(bundle)
|
|
203
209
|
typer.echo('')
|
|
204
210
|
typer.echo('View files:')
|
|
205
211
|
typer.echo(f'open {bundle}')
|
|
@@ -226,7 +232,7 @@ def _print_session_finished(status: dict, *, include_contribution_help: bool=Tru
|
|
|
226
232
|
mode = get_settings().training_contribution_mode
|
|
227
233
|
typer.echo(f'Agent Training Contribution Mode: {training_contribution_mode_display(mode)}')
|
|
228
234
|
if mode == "private_internal_only":
|
|
229
|
-
|
|
235
|
+
_print_private_internal_share_note(status.get('contribution_bundle_path'))
|
|
230
236
|
typer.echo('')
|
|
231
237
|
typer.echo('View files:')
|
|
232
238
|
typer.echo(f"open {status.get('contribution_bundle_path')}")
|
|
@@ -1439,6 +1445,8 @@ def start(
|
|
|
1439
1445
|
status = read_run_status(run_root)
|
|
1440
1446
|
if quiet:
|
|
1441
1447
|
_print_task_result(status, include_contribution_help=False)
|
|
1448
|
+
elif not json_progress:
|
|
1449
|
+
_print_task_result(status)
|
|
1442
1450
|
_handle_ecosystem_auto_share(status, quiet=quiet, json_progress=json_progress)
|
|
1443
1451
|
|
|
1444
1452
|
@app.command('run')
|
|
@@ -1652,7 +1660,7 @@ def status(run_id: str=typer.Argument(..., help='Run id or path to inspect.')):
|
|
|
1652
1660
|
typer.echo(format_run_status(read_run_status(run_root)))
|
|
1653
1661
|
|
|
1654
1662
|
|
|
1655
|
-
@app.command('watch')
|
|
1663
|
+
@app.command('watch', help='Watch live run progress, loop reviews, artifacts, and Experience Compiler status.')
|
|
1656
1664
|
def watch(
|
|
1657
1665
|
run_id: str=typer.Argument(..., help='Run id or path to watch.'),
|
|
1658
1666
|
interval: float=typer.Option(1.0, '--interval', help='Polling interval in seconds.'),
|
|
@@ -3940,17 +3948,25 @@ def bundle_check(path: Path=typer.Argument(..., help='Experience Compilation fol
|
|
|
3940
3948
|
|
|
3941
3949
|
issues: list[str] = []
|
|
3942
3950
|
bundle = Path(path).expanduser()
|
|
3943
|
-
|
|
3951
|
+
manifest_candidates = [
|
|
3952
|
+
bundle / "contribution_manifest.json",
|
|
3953
|
+
bundle / "task_manifest.json",
|
|
3954
|
+
bundle / "package_manifest.json",
|
|
3955
|
+
bundle / "manifest.json",
|
|
3956
|
+
bundle / "experience_compiler" / "compiler_manifest.json",
|
|
3957
|
+
]
|
|
3958
|
+
manifest_path = next((candidate for candidate in manifest_candidates if candidate.exists()), manifest_candidates[0])
|
|
3944
3959
|
if not bundle.exists():
|
|
3945
3960
|
issues.append(f"Bundle path does not exist: {bundle}")
|
|
3946
3961
|
elif not manifest_path.exists():
|
|
3947
|
-
|
|
3962
|
+
candidate_names = ", ".join(str(candidate.relative_to(bundle)) for candidate in manifest_candidates)
|
|
3963
|
+
issues.append(f"Experience Compilation manifest not found. Checked: {candidate_names}")
|
|
3948
3964
|
manifest_data = {}
|
|
3949
3965
|
if manifest_path.exists():
|
|
3950
3966
|
try:
|
|
3951
3967
|
manifest_data = read_json(manifest_path)
|
|
3952
3968
|
except Exception as exc:
|
|
3953
|
-
issues.append(f"
|
|
3969
|
+
issues.append(f"{manifest_path.relative_to(bundle)} could not be parsed: {exc}")
|
|
3954
3970
|
artifact_index_path = bundle / "outputs" / "artifacts_index.json"
|
|
3955
3971
|
artifacts: list[dict] = []
|
|
3956
3972
|
if artifact_index_path.exists():
|
|
@@ -4012,6 +4028,56 @@ def bundle_check(path: Path=typer.Argument(..., help='Experience Compilation fol
|
|
|
4012
4028
|
read_json(file_path)
|
|
4013
4029
|
except Exception as exc:
|
|
4014
4030
|
issues.append(f"{file_path.relative_to(bundle)} could not be parsed: {exc}")
|
|
4031
|
+
source_map_path = compiler_dir / "source_evidence_map.json"
|
|
4032
|
+
if source_map_path.exists():
|
|
4033
|
+
try:
|
|
4034
|
+
source_map = read_json(source_map_path)
|
|
4035
|
+
evidence_ids = {
|
|
4036
|
+
str(item.get("evidence_id"))
|
|
4037
|
+
for item in source_map.get("evidence_catalog") or []
|
|
4038
|
+
if isinstance(item, dict) and item.get("evidence_id")
|
|
4039
|
+
}
|
|
4040
|
+
for link in source_map.get("row_evidence_links") or []:
|
|
4041
|
+
if not isinstance(link, dict):
|
|
4042
|
+
continue
|
|
4043
|
+
link_ids = link.get("evidence_ref_ids") or link.get("source_evidence_ids") or []
|
|
4044
|
+
for evidence_id in link_ids:
|
|
4045
|
+
if str(evidence_id) not in evidence_ids:
|
|
4046
|
+
issues.append(f"source_evidence_map row {link.get('row_id')} references unknown evidence id: {evidence_id}")
|
|
4047
|
+
orphan_count = (
|
|
4048
|
+
(source_map.get("coverage_statistics") or {}).get("orphan_evidence_id_count")
|
|
4049
|
+
if isinstance(source_map.get("coverage_statistics"), dict)
|
|
4050
|
+
else None
|
|
4051
|
+
)
|
|
4052
|
+
if orphan_count is None:
|
|
4053
|
+
orphan_count = (source_map.get("coverage") or {}).get("orphan_evidence_id_count")
|
|
4054
|
+
if orphan_count not in (None, 0):
|
|
4055
|
+
issues.append(f"source_evidence_map has orphan evidence ids: {orphan_count}")
|
|
4056
|
+
except Exception as exc:
|
|
4057
|
+
issues.append(f"{source_map_path.relative_to(bundle)} could not be validated: {exc}")
|
|
4058
|
+
seen_training_ids: set[str] = set()
|
|
4059
|
+
for file_path in compiler_dir.rglob("*.jsonl"):
|
|
4060
|
+
try:
|
|
4061
|
+
rows = read_jsonl(file_path)
|
|
4062
|
+
except Exception as exc:
|
|
4063
|
+
issues.append(f"{file_path.relative_to(bundle)} could not be parsed: {exc}")
|
|
4064
|
+
continue
|
|
4065
|
+
if "training_time_package" in file_path.parts or "eval_package" in file_path.parts or "loop_learning" in file_path.parts:
|
|
4066
|
+
for row in rows:
|
|
4067
|
+
if not isinstance(row, dict):
|
|
4068
|
+
continue
|
|
4069
|
+
row_id = row.get("row_id") or row.get("pair_id")
|
|
4070
|
+
if row_id:
|
|
4071
|
+
key = f"{file_path.relative_to(compiler_dir)}:{row_id}"
|
|
4072
|
+
if key in seen_training_ids:
|
|
4073
|
+
issues.append(f"Duplicate generated row id: {row_id}")
|
|
4074
|
+
seen_training_ids.add(key)
|
|
4075
|
+
if row.get("data_type") and not (
|
|
4076
|
+
row.get("source_evidence_ref_ids")
|
|
4077
|
+
or row.get("source_evidence_ids")
|
|
4078
|
+
or row.get("evidence_refs")
|
|
4079
|
+
):
|
|
4080
|
+
issues.append(f"{file_path.relative_to(bundle)} row lacks evidence refs: {row_id or row.get('data_type')}")
|
|
4015
4081
|
loops_dir = bundle / "loops"
|
|
4016
4082
|
if loops_dir.exists():
|
|
4017
4083
|
for file_path in loops_dir.rglob("*.json"):
|
|
@@ -4024,11 +4090,6 @@ def bundle_check(path: Path=typer.Argument(..., help='Experience Compilation fol
|
|
|
4024
4090
|
read_jsonl(file_path)
|
|
4025
4091
|
except Exception as exc:
|
|
4026
4092
|
issues.append(f"{file_path.relative_to(bundle)} could not be parsed: {exc}")
|
|
4027
|
-
for file_path in compiler_dir.rglob("*.jsonl"):
|
|
4028
|
-
try:
|
|
4029
|
-
read_jsonl(file_path)
|
|
4030
|
-
except Exception as exc:
|
|
4031
|
-
issues.append(f"{file_path.relative_to(bundle)} could not be parsed: {exc}")
|
|
4032
4093
|
surface_warnings: list[str] = []
|
|
4033
4094
|
for trace_path in [bundle / "traces" / "agent_traces.jsonl", bundle / "traces" / "raw_agent_traces.jsonl"]:
|
|
4034
4095
|
if not trace_path.exists():
|
|
@@ -4061,7 +4122,7 @@ def bundle_check(path: Path=typer.Argument(..., help='Experience Compilation fol
|
|
|
4061
4122
|
typer.echo(f"Task status: {status}")
|
|
4062
4123
|
for warning in surface_warnings[:10]:
|
|
4063
4124
|
typer.echo(f"Surface completeness warning: {redact_secrets(warning)}")
|
|
4064
|
-
typer.echo("This Experience Compilation is ready
|
|
4125
|
+
typer.echo("This Experience Compilation is ready for local export, Runtime Training install, or explicit sharing.")
|
|
4065
4126
|
|
|
4066
4127
|
|
|
4067
4128
|
@bundle_app.command('contribute')
|