agent-tune-kit 2.3.3__tar.gz → 2.3.4__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.
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/.codex-plugin/plugin.json +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/PKG-INFO +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/__init__.py +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/shared/base.css +9 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/app.js +24 -9
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/page.html +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/styles.css +3 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/traces/app.js +55 -46
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/traces/page.html +5 -2
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/traces/styles.css +22 -3
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/traces.py +4 -29
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/trace-dashboard-design.md +17 -7
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/trace-project-attribution-design.md +9 -7
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/trace-tuning.md +4 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/pyproject.toml +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/validate_skill_pack.py +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-trace-detect/SKILL.md +2 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-trace-diagnose/SKILL.md +2 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-trace-init/SKILL.md +2 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-trace-optimize/SKILL.md +2 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-trace-verify/SKILL.md +2 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-visualize-trace/SKILL.md +6 -4
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_install_plugin.py +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_release_scripts.py +1 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_projects.py +9 -1
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_visualize_traces.py +8 -8
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/trace-dashboard.cjs +81 -8
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/.gitignore +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/README.en.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/README.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/__main__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/dataset.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/evaluation.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/main.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/output.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/results.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/trace.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/cli/visualize.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/datasets/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/datasets/prepare.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/datasets/truth.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/datasets/updates.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/datasets/validation.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/errors.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/calibration.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/logs.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/rules.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/runner.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/runtime.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/execution/tracing.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/installer.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/results/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/results/assessment.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/results/evidence.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/results/judgments.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/results/summary.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/results/versions.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/archive.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/capture.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/categories.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/langfuse.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/migrate.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/progress.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/projects.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/query.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/records.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/segments.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/traces/store.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/utils/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/utils/csv_io.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/utils/files.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/dataset/app.js +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/dataset/page.html +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/dataset/styles.css +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/dataset/vendor/echarts.min.js +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/failures/app.js +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/failures/page.html +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/failures/styles.css +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/lanes.js +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/vendor/markdown-it.LICENSE +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/vendor/markdown-it.min.js +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/dataset.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/failures.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/fields.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/history.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/render.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/timeline.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/trace.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/workspace.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/assets/agent_tune_kit_evaluation.png +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/assets/agent_tune_kit_trace.png +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/assets/arch-en.png +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/assets/arch.png +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/assets/architecture.en.svg +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/assets/architecture.svg +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/ato-atk-project-boundary-recommendation-2026-11-05.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/cli-skill-modularization-plan.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/codex_agent_tuning_prd.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/execution-evidence-and-tracing-plan.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/ground-truth-and-grading-assessment-2026-10-25.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/local-context.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/shared-versioning-and-confirmation.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/skill-template-pack-usage.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/surginame-atk-capability-review-2026-10-27.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/trace-change-verification-readability-diagnosis.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/trace-swimlane-design.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/trace-tuning-validation.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/docs/truth-and-assessment.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/check-release.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/dev-refresh-install.sh +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/install_plugin.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/publish-pypi.sh +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/publish-release.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/release-version.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/scripts/release-version.sh +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-dataset/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-dataset/scripts/update_dataset.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-diagnose/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-eval/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-init/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-optimize/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-report/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-trace-capture/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-visualize-dataset/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-visualize-dataset/scripts/generate_dataset_browser.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-visualize-failures/SKILL.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/skills/atk-visualize-failures/scripts/generate_failure_browser.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/templates/.atk/runner/eval_runner.py.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/templates/.atk/runner/failure_rule.py.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/templates/.atk/runner/import_evidence.py.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/templates/.gitkeep +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/__init__.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/conftest.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/fixtures/legacy_eval_runner.py.txt +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/fixtures/managed_v1.py.md +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_assessment_contract.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_atk_init_contract.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_cli_workflow.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_dataset_updates.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_diagnosis.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_evidence_import.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_evidence_judgments.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_evidence_packaging.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_evidence_versions.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_execution_evidence.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_execution_outcomes.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_execution_tracing.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_generate_dataset_browser.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_generate_failure_browser.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_judge_calibration.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_local_context.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_plugin_cache.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_runner_output_columns.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_runner_template_row_logging.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_runtime_contracts.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_snapshot_reads.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_capture.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_categories.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_cli.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_langfuse.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_progress.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_query.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_records.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_segments.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_trace_store.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_truth_browser.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_truth_cli.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_truth_contract.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_truth_runner.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_v2_progress.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/test_visualize_trace.py +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/trace-event-wheel.cjs +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/trace-preview-scroll.cjs +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/trace-selection-reason.cjs +0 -0
- {agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/tests/trace-stage-cards.cjs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-tune-kit",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.4",
|
|
4
4
|
"description": "Local Codex plugin for batch Agent evaluation and session trace tuning with evidence-backed issues, focused changes, verification and offline review.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "hustyichi",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agent-tune-kit
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.4
|
|
4
4
|
Summary: Local Codex plugin for iterative Agent tuning with guided Skills, reusable runner templates, versioned results, and static validation.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hustyichi/agent-tune-kit
|
|
6
6
|
Project-URL: Repository, https://github.com/hustyichi/agent-tune-kit
|
{agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/shared/base.css
RENAMED
|
@@ -93,3 +93,12 @@ select:hover { border-color: #9baebb }
|
|
|
93
93
|
.drawer.above-record { inset: 0 0 auto; border-radius: 0 0 12px 12px; border-top: 0; border-bottom: 1px solid var(--line) }
|
|
94
94
|
.drawer-resizer { display: none }
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
/* Project attribution belongs to issues; the menu is shared by both issue views. */
|
|
98
|
+
.project-choice { position: relative; margin-bottom: 7px; font-size: 13px }
|
|
99
|
+
.project-choice summary { height: 34px; padding: 6px 12px; border: 1px solid #cdd8e1; border-radius: 6px; background: white }
|
|
100
|
+
.project-choice summary:hover { border-color: #9baebb }
|
|
101
|
+
.project-menu { position: absolute; right: 0; z-index: 20; width: min(300px, 80vw); max-height: 320px; overflow: auto; padding: 12px; border: 1px solid var(--line); border-radius: 6px; background: white; box-shadow: 0 6px 20px #0002 }
|
|
102
|
+
.project-menu p { margin: 0 0 8px }
|
|
103
|
+
#project-filter label { display: flex; align-items: center; gap: 8px; padding: 6px 0 }
|
|
104
|
+
#project-filter input { width: 16px; height: 16px; min-width: 16px; padding: 0 }
|
|
@@ -29,10 +29,25 @@
|
|
|
29
29
|
return roots.some(root => { let current = root.id; const seen = new Set(); while (current && !seen.has(current)) { if (current === id) return true; seen.add(current); current = data.projects?.[current]?.parent_id; } return false; });
|
|
30
30
|
});
|
|
31
31
|
const projectText = item => (item.root_projects || []).map(p => p.name + (p.pending ? "(待确认)" : "")).join("、") || "待归因";
|
|
32
|
-
|
|
33
|
-
for (const
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const projectInputs = [];
|
|
33
|
+
for (const p of [{id: "~unattributed", name: "待归因"}, ...Object.values(data.projects || {})]) {
|
|
34
|
+
const label = el("label"), input = el("input");
|
|
35
|
+
input.type = "checkbox"; input.value = p.id;
|
|
36
|
+
input.checked = projectSelection.has(p.id);
|
|
37
|
+
label.append(input, document.createTextNode(p.abbreviation || p.name));
|
|
38
|
+
$("project-filter").append(label); projectInputs.push(input);
|
|
39
|
+
input.onchange = () => $("project-filter").onchange();
|
|
40
|
+
}
|
|
41
|
+
const updateProjectSummary = () => {
|
|
42
|
+
$("project-summary").textContent = projectSelection.size ? `关联项目:已选 ${projectSelection.size} 项` : "关联项目:全部";
|
|
43
|
+
};
|
|
44
|
+
updateProjectSummary();
|
|
45
|
+
$("project-clear").onclick = () => { projectInputs.forEach(input => { input.checked = false; }); $("project-filter").onchange(); };
|
|
46
|
+
$("project-choice").onkeydown = event => { if (event.key === "Escape") { $("project-choice").open = false; $("project-summary").focus(); } };
|
|
47
|
+
document.addEventListener("click", event => {
|
|
48
|
+
if (!event.target.closest("#project-choice")) $("project-choice").open = false;
|
|
49
|
+
});
|
|
50
|
+
|
|
36
51
|
const filters = ["trace-filter", "type-filter", "trace-search", "record-mode"];
|
|
37
52
|
const list = $("trace-list"), scroller = $("trace-scroll");
|
|
38
53
|
const scope = () => $("trace-filter").value === "" ? null : Number($("trace-filter").value);
|
|
@@ -291,7 +306,7 @@
|
|
|
291
306
|
if (snapshot?.project_links) {
|
|
292
307
|
const entries = new Map((snapshot.project_registry?.projects || []).map(p => [p.id, p]));
|
|
293
308
|
const names = snapshot.project_links.filter(p => p.role === "root_cause").map(p => { const entry = entries.get(p.project_id); return (entry?.abbreviation || entry?.name || p.project_id) + (p.evidence_state === "supported" ? "" : "(待确认)"); });
|
|
294
|
-
body.prepend(el("p",
|
|
309
|
+
body.prepend(el("p", `诊断时的关联项目:${names.join("、") || "待归因"}`));
|
|
295
310
|
}
|
|
296
311
|
const name = diagnosis.reference.path.split("/").pop();
|
|
297
312
|
details.append(el("summary", `展开原诊断 · ${name}`), body);
|
|
@@ -391,7 +406,7 @@
|
|
|
391
406
|
$("drawer-content").append(tabs);
|
|
392
407
|
if (stage === "issue") {
|
|
393
408
|
const description = section("问题描述");
|
|
394
|
-
description.append(el("p",
|
|
409
|
+
description.append(el("p", `关联项目:${projectText(item)}`), el("p", issue.description || issue.title));
|
|
395
410
|
$("drawer-content").append(description);
|
|
396
411
|
if (typeof issue.selection_reason === "string" && issue.selection_reason.trim()) {
|
|
397
412
|
const reason = section("保留理由");
|
|
@@ -1013,9 +1028,9 @@
|
|
|
1013
1028
|
const head = el("div", undefined, "issue-card-head");
|
|
1014
1029
|
head.append(el("span", issue.id, "issue-id-text"), el("span", undefined, `progress-dot ${progress.klass}`));
|
|
1015
1030
|
const body = el("div", undefined, "issue-card-body");
|
|
1016
|
-
const projects = el("p",
|
|
1031
|
+
const projects = el("p", `关联项目:${projectText(item)}`);
|
|
1017
1032
|
if (data.dashboard.available) for (const project of item.root_projects || []) {
|
|
1018
|
-
const link = el("a", project.name); link.href = dashboardHash(`view=
|
|
1033
|
+
const link = el("a", project.name); link.href = dashboardHash(`view=category&project=${encodeURIComponent(project.id)}`); projects.append(link);
|
|
1019
1034
|
}
|
|
1020
1035
|
body.append(projects);
|
|
1021
1036
|
body.append(el("h3", issue.title || "问题"), el("div", progress.label, "issue-progress"));
|
|
@@ -1107,7 +1122,7 @@
|
|
|
1107
1122
|
$("capture-filter").closest("label").hidden = Boolean(currentCapture?.current);
|
|
1108
1123
|
options($("capture-filter"), data.captures.map(c => c.id));
|
|
1109
1124
|
if (currentCapture) $("capture-filter").value = currentCapture.id;
|
|
1110
|
-
$("project-filter").onchange = () => { projectSelection.clear(); for (const
|
|
1125
|
+
$("project-filter").onchange = () => { projectSelection.clear(); for (const input of projectInputs) if (input.checked) projectSelection.add(input.value); updateProjectSummary(); const params = new URLSearchParams(location.hash.slice(1)); params.delete("project"); for (const id of projectSelection) params.append("project", id); history.replaceState(null, "", `#${params}`); renderIssueRail(); };
|
|
1111
1126
|
$("capture-filter").onchange = () => { investigation = null; scopeBefore = null; railFilter = null; chooseCapture(); renderIssueRail(); renderTraces(); };
|
|
1112
1127
|
$("trace-filter").onchange = () => focusTrace(scope());
|
|
1113
1128
|
for (const id of ["trace-search","type-filter","record-mode"]) $(id).addEventListener(id === "trace-search" ? "input" : "change", () => renderTraces());
|
{agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/page.html
RENAMED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
</div>
|
|
22
22
|
<div class="rail-filters">
|
|
23
23
|
<label class="search-label"><span class="sr-only">搜索问题</span><input id="issue-search" type="search" placeholder="搜索问题"></label>
|
|
24
|
-
<
|
|
24
|
+
<details id="project-choice" class="project-choice"><summary id="project-summary">关联项目:全部</summary><div class="project-menu"><p>含子项目</p><button id="project-clear" type="button">清空筛选</button><div id="project-filter" role="group" aria-label="关联项目"></div></div></details>
|
|
25
25
|
<label><span class="sr-only">状态</span><select id="issue-status"></select></label>
|
|
26
26
|
</div>
|
|
27
27
|
<div id="issue-rail-list" class="rail-list"></div>
|
{agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/trace/styles.css
RENAMED
|
@@ -30,6 +30,9 @@ body.rail-collapsed #rail-toggle { transform: rotate(180deg) }
|
|
|
30
30
|
.rail-filters .search-label { flex: 1; min-width: 0 }
|
|
31
31
|
.rail-filters input, .rail-filters select { width: 100%; height: 32px; font-size: 12px; padding: 0 8px }
|
|
32
32
|
.rail-filters select { width: auto; min-width: 88px }
|
|
33
|
+
.rail-filters .project-choice { margin-bottom: 0; font-size: 12px }
|
|
34
|
+
.rail-filters .project-choice summary { height: 32px; padding: 6px 8px; white-space: nowrap }
|
|
35
|
+
.rail-filters .project-menu { left: 0; right: auto }
|
|
33
36
|
.rail-list { flex: 1; min-height: 0; overflow: auto; padding: 8px; display: flex; flex-direction: column; gap: 8px }
|
|
34
37
|
.issue-card { display: flex; flex-direction: column; gap: 6px; width: 100%; text-align: left; padding: 10px }
|
|
35
38
|
.issue-card-head { justify-content: space-between; gap: 6px; width: 100% }
|
|
@@ -11,14 +11,28 @@
|
|
|
11
11
|
const button = (text, action, className) => { const node = el("button", text, className); node.type = "button"; node.onclick = action; return node; };
|
|
12
12
|
|
|
13
13
|
const projectSelection = new Set(new URLSearchParams(location.hash.slice(1)).getAll("project"));
|
|
14
|
-
const projectMatches = item => !projectSelection.size || [...projectSelection].some(id => {
|
|
14
|
+
const projectMatches = item => state.view === "session" || !projectSelection.size || [...projectSelection].some(id => {
|
|
15
15
|
const roots = item.root_projects || [];
|
|
16
16
|
if (id === "~unattributed") return !roots.length;
|
|
17
17
|
return roots.some(root => { let current = root.id; const seen = new Set(); while (current && !seen.has(current)) { if (current === id) return true; seen.add(current); current = data.projects?.[current]?.parent_id; } return false; });
|
|
18
18
|
});
|
|
19
19
|
const projectText = item => (item.root_projects || []).map(p => p.name + (p.pending ? "(待确认)" : "")).join("、") || "待归因";
|
|
20
|
-
|
|
21
|
-
for (const
|
|
20
|
+
const projectInputs = [];
|
|
21
|
+
for (const p of [{id: "~unattributed", name: "待归因"}, ...Object.values(data.projects || {})]) {
|
|
22
|
+
const label = el("label"), input = el("input");
|
|
23
|
+
input.type = "checkbox"; input.value = p.id;
|
|
24
|
+
input.checked = projectSelection.has(p.id);
|
|
25
|
+
label.append(input, document.createTextNode(p.abbreviation || p.name));
|
|
26
|
+
$("project-filter").append(label); projectInputs.push(input);
|
|
27
|
+
input.onchange = () => $("project-filter").onchange();
|
|
28
|
+
}
|
|
29
|
+
const updateProjectSummary = () => {
|
|
30
|
+
$("project-summary").textContent = projectSelection.size ? `关联项目:已选 ${projectSelection.size} 项` : "关联项目:全部";
|
|
31
|
+
};
|
|
32
|
+
updateProjectSummary();
|
|
33
|
+
$("project-clear").onclick = () => { projectInputs.forEach(input => { input.checked = false; }); $("project-filter").onchange(); };
|
|
34
|
+
$("project-choice").onkeydown = event => { if (event.key === "Escape") { $("project-choice").open = false; $("project-summary").focus(); } };
|
|
35
|
+
|
|
22
36
|
|
|
23
37
|
const NONE = "~uncategorized"; // cannot collide with a kebab-case category ID
|
|
24
38
|
const ORDER = new Map(data.progress_legend.map((entry, index) => [entry.key, index]));
|
|
@@ -37,7 +51,6 @@
|
|
|
37
51
|
return `${part.month}-${part.day} ${part.hour === "24" ? "00" : part.hour}:${part.minute}`;
|
|
38
52
|
};
|
|
39
53
|
const sourceText = source => [source.type, source.environment].filter(Boolean).join(" · ") || "来源未记录";
|
|
40
|
-
const scaleText = s => s.traces != null && s.observations != null ? `${s.traces} Trace · ${s.observations} 观测` : `${s.files} 个归档文件`;
|
|
41
54
|
const statusText = value => STATUS[value] || value || "未记录";
|
|
42
55
|
|
|
43
56
|
// --- derived search text and source scope ---------------------------------------------------------------------
|
|
@@ -53,7 +66,7 @@
|
|
|
53
66
|
const matchIssue = (s, issue) =>
|
|
54
67
|
projectMatches(issue) && (!state.progress || issue.progress === state.progress) && (!state.q || s._text.includes(state.q) || issue._text.includes(state.q));
|
|
55
68
|
const matchSession = s => s.issues.some(issue => matchIssue(s, issue)) ||
|
|
56
|
-
(!s.issues.length && !projectSelection.size && !state.progress && (!state.q || s._text.includes(state.q)));
|
|
69
|
+
(!s.issues.length && (state.view === "session" || !projectSelection.size) && !state.progress && (!state.q || s._text.includes(state.q)));
|
|
57
70
|
const byProgress = (a, b) => ORDER.get(a.progress) - ORDER.get(b.progress) || a.id.localeCompare(b.id, undefined, {numeric: true});
|
|
58
71
|
|
|
59
72
|
// --- small building blocks ------------------------------------------------------------------------------------
|
|
@@ -181,7 +194,6 @@
|
|
|
181
194
|
}
|
|
182
195
|
card.append(el("div", `${sourceText(s.source)} · 更新 ${when(s.updated_ms)}`, "card-meta"));
|
|
183
196
|
const matched = s.issues.filter(issue => matchIssue(s, issue));
|
|
184
|
-
card.append(el("p", `根因项目:${[...new Set(matched.map(projectText))].join("、") || "待归因"}`));
|
|
185
197
|
if (matched.length) {
|
|
186
198
|
const counts = countBy(matched);
|
|
187
199
|
const row = el("div", undefined, "card-count");
|
|
@@ -233,7 +245,7 @@
|
|
|
233
245
|
const counts = countBy(items.map(item => item.issue));
|
|
234
246
|
const row = el("div", undefined, "card-count");
|
|
235
247
|
row.append(el("strong", `${new Set(items.map(item => item.s.dir)).size} 个会话 · ${items.length} 个问题`), el("span", `最近 ${when(latestOf(items) < 0 ? null : latestOf(items))}`, "muted"));
|
|
236
|
-
card.append(el("p",
|
|
248
|
+
card.append(el("p", `关联项目:${[...new Set(items.map(({issue}) => projectText(issue)))].join("、")}`));
|
|
237
249
|
card.append(row, miniBar(counts), el("div", topProgress(counts), "card-meta"));
|
|
238
250
|
return card;
|
|
239
251
|
}
|
|
@@ -261,12 +273,12 @@
|
|
|
261
273
|
function issueRow(s, issue, withCategory) {
|
|
262
274
|
const row = el("div", undefined, "issue-row");
|
|
263
275
|
const dot = el("span", undefined, `progress-dot ${issue.progress}`); dot.title = LABEL.get(issue.progress);
|
|
264
|
-
const href = `${s.href}#issue=${encodeURIComponent(issue.id)}${[...projectSelection].map(id => `&project=${encodeURIComponent(id)}`).join("")}`;
|
|
276
|
+
const href = `${s.href}#issue=${encodeURIComponent(issue.id)}${(state.view === "category" ? [...projectSelection] : []).map(id => `&project=${encodeURIComponent(id)}`).join("")}`;
|
|
265
277
|
const title = el("a", issue.title || issue.id, "row-title"); title.href = href; title.title = `${issue.id} ${issue.title}`;
|
|
266
278
|
const jump = el("a", "↗", "row-jump"); jump.href = href; jump.setAttribute("aria-label", `在会话页打开 ${issue.id}`);
|
|
267
279
|
// Title gets the full first line and may wrap; category and progress sit on their own line beneath it.
|
|
268
280
|
const meta = el("div", undefined, "row-meta");
|
|
269
|
-
meta.append(el("span",
|
|
281
|
+
meta.append(el("span", `关联项目:${projectText(issue)}`, "project-tag"));
|
|
270
282
|
if (withCategory) meta.append(categoryChip(issue.category));
|
|
271
283
|
meta.append(el("span", LABEL.get(issue.progress), "row-progress"));
|
|
272
284
|
row.append(dot, el("span", shortIssue(issue.id), "issue-id-text"), title, jump, meta);
|
|
@@ -275,7 +287,7 @@
|
|
|
275
287
|
function issueList(box, s, issues, withCategory) {
|
|
276
288
|
const rows = issues.filter(issue => matchIssue(s, issue)).sort(byProgress);
|
|
277
289
|
const list = el("div", undefined, "issue-list");
|
|
278
|
-
if (!rows.length) list.append(el("div", issues.length ? "没有符合筛选条件的问题。" : "
|
|
290
|
+
if (!rows.length) list.append(el("div", issues.length ? "没有符合筛选条件的问题。" : "无保留问题(不代表会话正确)。", "empty"));
|
|
279
291
|
for (const issue of rows) list.append(issueRow(s, issue, withCategory));
|
|
280
292
|
box.append(list);
|
|
281
293
|
return {shown: rows.length, total: issues.length};
|
|
@@ -283,40 +295,35 @@
|
|
|
283
295
|
const textDetails = (title, build) => { const node = el("details", undefined, "detail-section"); node.append(el("summary", title)); build(node); return node; };
|
|
284
296
|
const bullets = (node, items) => { const list = el("ul"); for (const item of items) list.append(el("li", item)); node.append(list); };
|
|
285
297
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (!s.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
const meta = el("div", undefined, "drawer-meta");
|
|
294
|
-
for (const text of [sourceText(s.source), scaleText(s), `归档 ${when(s.archived_ms)}`, `更新 ${when(s.updated_ms)}`]) meta.append(el("span", text));
|
|
295
|
-
box.append(meta);
|
|
296
|
-
const origin = [s.source.instance, s.source.project].filter(Boolean).join(" / ");
|
|
297
|
-
if (origin) box.append(el("p", origin, "mono muted"));
|
|
298
|
-
if (!s.preview.exists || s.preview.stale) {
|
|
299
|
-
const note = el("p", s.preview.exists ? "会话页早于最近一次记录写入。刷新命令:" : "会话页尚未生成。生成命令:", "warning");
|
|
300
|
-
note.append(el("code", `atk visualize trace --session-id ${s.session_id} --overwrite --no-open`));
|
|
301
|
-
box.append(note);
|
|
298
|
+
// The session drawer is a preview: the header carries identity and the way in; below it at most a few one-line
|
|
299
|
+
// notes appear, and only when something makes the issue list untrustworthy or needs an action. Source, scale and
|
|
300
|
+
// full detection coverage live on the session page (「会话信息」).
|
|
301
|
+
function sessionNotes(s, box) {
|
|
302
|
+
if (!s.detection) box.append(el("p", "尚未检测,问题列表为空不代表会话没有问题。", "warning"));
|
|
303
|
+
else if (s.detection.status !== "completed") {
|
|
304
|
+
box.append(el("p", `最近一次检测${statusText(s.detection.status)},问题可能不全;检测缺口见会话页「会话信息」。`, "warning"));
|
|
302
305
|
}
|
|
303
306
|
if (s.problem_count) {
|
|
304
|
-
|
|
305
|
-
bullets(
|
|
306
|
-
if (s.problem_count > s.problems.length)
|
|
307
|
-
})
|
|
307
|
+
const node = textDetails(`${s.problem_count} 条记录读取失败`, inner => {
|
|
308
|
+
bullets(inner, s.problems);
|
|
309
|
+
if (s.problem_count > s.problems.length) inner.append(el("p", `另有 ${s.problem_count - s.problems.length} 条未显示。`, "muted"));
|
|
310
|
+
});
|
|
311
|
+
node.classList.add("warning"); box.append(node);
|
|
312
|
+
}
|
|
313
|
+
if (!s.preview.exists || s.preview.stale) {
|
|
314
|
+
const command = `atk visualize trace --session-id ${s.session_id} --overwrite --no-open`;
|
|
315
|
+
const note = el("p", s.preview.exists ? "会话页已过期,不含最近的记录。" : "会话页尚未生成。", "warning note-row");
|
|
316
|
+
const copy = copyButton(command, s.preview.exists ? "复制刷新命令" : "复制生成命令", s.preview.exists ? "复制刷新命令" : "复制生成命令");
|
|
317
|
+
copy.title = command; note.append(copy); box.append(note);
|
|
308
318
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (s.capture.gaps.length) { node.append(el("p", "采集缺口:")); bullets(node, s.capture.gaps); }
|
|
318
|
-
if (!s.issues.length) node.append(el("p", "没有保留问题不代表会话正确,请结合检测范围与缺口判断。", "muted"));
|
|
319
|
-
}));
|
|
319
|
+
}
|
|
320
|
+
function sessionDrawer(s, box) {
|
|
321
|
+
$("drawer-title").textContent = s.session_id;
|
|
322
|
+
$("drawer-title-tools").append(copyButton(s.session_id, "复制 Session ID"));
|
|
323
|
+
if (s.error) { box.append(el("p", `会话记录不可读取:${s.error}`, "warning")); return; }
|
|
324
|
+
const open = el("a", "打开会话页 ↗", "link-button primary"); open.href = s.href;
|
|
325
|
+
$("drawer-tools").append(open);
|
|
326
|
+
sessionNotes(s, box);
|
|
320
327
|
const heading = el("div", undefined, "list-heading");
|
|
321
328
|
const label = el("span", "问题"); heading.append(label); box.append(heading);
|
|
322
329
|
const counts = issueList(box, s, s.issues, true);
|
|
@@ -356,7 +363,7 @@
|
|
|
356
363
|
if (state.view === "session" && !session) { state.drawer = null; drawer.hidden = true; shown = null; return; }
|
|
357
364
|
const id = `${state.view}:${state.drawer}`, fresh = shown !== id;
|
|
358
365
|
const box = $("drawer-content"), keep = fresh ? 0 : box.scrollTop;
|
|
359
|
-
box.replaceChildren();
|
|
366
|
+
box.replaceChildren(); $("drawer-title-tools").replaceChildren(); $("drawer-tools").replaceChildren();
|
|
360
367
|
if (session) sessionDrawer(session, box); else categoryDrawer(state.drawer, box);
|
|
361
368
|
drawer.hidden = false; box.scrollTop = keep; shown = id;
|
|
362
369
|
if (fresh) $("drawer-close").focus({preventScroll: true});
|
|
@@ -371,7 +378,7 @@
|
|
|
371
378
|
|
|
372
379
|
// --- navigation -----------------------------------------------------------------------------------------------
|
|
373
380
|
function syncHash() {
|
|
374
|
-
const parts = [`view=${state.view}`, ...[...projectSelection].map(id => `project=${encodeURIComponent(id)}`)];
|
|
381
|
+
const parts = [`view=${state.view}`, ...(state.view === "category" ? [...projectSelection].map(id => `project=${encodeURIComponent(id)}`) : [])];
|
|
375
382
|
if (state.drawer !== null) parts.push(`${state.view}=${encodeURIComponent(state.drawer)}`);
|
|
376
383
|
const next = `#${parts.join("&")}`;
|
|
377
384
|
if (location.hash !== next) history.replaceState(null, "", next);
|
|
@@ -383,8 +390,8 @@
|
|
|
383
390
|
function applyHash() {
|
|
384
391
|
const params = new URLSearchParams(location.hash.slice(1));
|
|
385
392
|
projectSelection.clear(); params.getAll("project").forEach(id => projectSelection.add(id));
|
|
386
|
-
for (const
|
|
387
|
-
const view = params.get("view") === "category" ? "category" : "session";
|
|
393
|
+
for (const input of projectInputs) input.checked = projectSelection.has(input.value); updateProjectSummary();
|
|
394
|
+
const view = params.get("view") === "category" || (projectSelection.size && !params.get("session")) ? "category" : "session";
|
|
388
395
|
let drawer = null;
|
|
389
396
|
if (view === "session") {
|
|
390
397
|
const key = params.get("session");
|
|
@@ -398,6 +405,7 @@
|
|
|
398
405
|
}
|
|
399
406
|
|
|
400
407
|
function render() {
|
|
408
|
+
$("project-choice").hidden = state.view === "session";
|
|
401
409
|
renderTabs(); renderProgress(); renderNote();
|
|
402
410
|
const grid = $("dash-grid"), strip = $("dash-strip");
|
|
403
411
|
grid.replaceChildren(); strip.replaceChildren();
|
|
@@ -430,7 +438,7 @@
|
|
|
430
438
|
$(id).onclick = () => setView(view);
|
|
431
439
|
$(id).onkeydown = onTabKey;
|
|
432
440
|
}
|
|
433
|
-
$("project-filter").onchange = () => { projectSelection.clear(); for (const
|
|
441
|
+
$("project-filter").onchange = () => { projectSelection.clear(); for (const input of projectInputs) if (input.checked) projectSelection.add(input.value); updateProjectSummary(); syncHash(); render(); };
|
|
434
442
|
$("dash-search").oninput = event => { state.q = event.target.value.trim().toLowerCase(); render(); };
|
|
435
443
|
$("drawer-close").onclick = closeDrawer;
|
|
436
444
|
document.addEventListener("keydown", event => {
|
|
@@ -445,6 +453,7 @@
|
|
|
445
453
|
let pressedOutside = false;
|
|
446
454
|
document.addEventListener("pointerdown", event => { pressedOutside = state.drawer !== null && dismissable(event.target); });
|
|
447
455
|
document.addEventListener("click", event => {
|
|
456
|
+
if (!event.target.closest("#project-choice")) $("project-choice").open = false;
|
|
448
457
|
const close = pressedOutside && state.drawer !== null && dismissable(event.target);
|
|
449
458
|
pressedOutside = false;
|
|
450
459
|
if (close) closeDrawer();
|
{agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/traces/page.html
RENAMED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<button id="tab-category" type="button" role="tab" aria-controls="dash-panel">异常</button>
|
|
21
21
|
</div>
|
|
22
22
|
<label class="search-label"><span class="sr-only">搜索</span><input id="dash-search" type="search" placeholder="搜索 Session ID、问题编号、标题、分类"></label>
|
|
23
|
-
<
|
|
23
|
+
<details id="project-choice" class="project-choice"><summary id="project-summary">关联项目:全部</summary><div class="project-menu"><p>含子项目</p><button id="project-clear" type="button">清空筛选</button><div id="project-filter" role="group" aria-label="关联项目"></div></div></details>
|
|
24
24
|
<label id="source-choice" hidden><span class="sr-only">来源</span><select id="source-filter"></select></label>
|
|
25
25
|
</div>
|
|
26
26
|
<div id="dash-panel" class="dash-panel" role="tabpanel" aria-labelledby="tab-session">
|
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
</main>
|
|
36
36
|
<aside id="drawer" class="drawer" role="dialog" aria-modal="false" aria-labelledby="drawer-title" hidden tabindex="-1">
|
|
37
37
|
<div class="drawer-resizer" id="drawer-resizer" aria-hidden="true"></div>
|
|
38
|
-
<div class="drawer-header"
|
|
38
|
+
<div class="drawer-header">
|
|
39
|
+
<div class="drawer-heading"><h2 id="drawer-title"></h2><span id="drawer-title-tools"></span></div>
|
|
40
|
+
<div class="drawer-tools"><span id="drawer-tools"></span><button id="drawer-close" type="button" aria-label="关闭详情">关闭 ×</button></div>
|
|
41
|
+
</div>
|
|
39
42
|
<div id="drawer-content" class="drawer-content"></div>
|
|
40
43
|
</aside>
|
|
41
44
|
<script id="dashboard-data" type="application/json">__DATA__</script>
|
{agent_tune_kit-2.3.3 → agent_tune_kit-2.3.4}/agent_tune_kit/visualize/assets/traces/styles.css
RENAMED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
.dash-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; border-bottom: 1px solid var(--line) }
|
|
13
13
|
.dash-controls .search-label { flex: 1 1 260px; max-width: 440px; min-width: 0; margin-left: auto }
|
|
14
14
|
.dash-controls .search-label, #source-choice { margin-bottom: 7px }
|
|
15
|
+
/* Keep the toolbar geometry when the issue-only project filter is hidden. */
|
|
16
|
+
.dash-controls #project-choice[hidden] { display: block !important; visibility: hidden }
|
|
15
17
|
.view-tabs { display: flex; gap: 4px }
|
|
16
18
|
.view-tabs [role=tab] { height: 40px; margin-bottom: -1px; padding: 0 16px; border: 0; border-bottom: 2px solid transparent; border-radius: 6px 6px 0 0; background: transparent; color: var(--muted); font-weight: 600 }
|
|
17
19
|
.view-tabs [role=tab]:hover { color: var(--ink); background: #edf1f4 }
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
.filter-note { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted) }
|
|
41
43
|
.filter-note button { font-size: 12px; padding: 2px 8px }
|
|
42
44
|
|
|
43
|
-
.dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; align-items:
|
|
45
|
+
.dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; align-items: stretch }
|
|
44
46
|
.dash-card { position: relative; display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 12px 14px }
|
|
45
47
|
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0 }
|
|
46
48
|
.card-head .card-open { flex: 1 1 0 }
|
|
@@ -70,7 +72,19 @@ button.category-tag:hover { background: #ffe8d2 }
|
|
|
70
72
|
.empty-dash { padding: 28px; text-align: center; color: var(--muted); border: 1px dashed var(--line); border-radius: 8px; background: white }
|
|
71
73
|
|
|
72
74
|
.drawer-meta { font-size: 12px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 2px 12px; margin-bottom: 10px }
|
|
73
|
-
|
|
75
|
+
/* Header: Session ID with its copy icon on the left; the way into the session page and close on the right. */
|
|
76
|
+
.drawer-heading { display: flex; align-items: center; gap: 4px; min-width: 0 }
|
|
77
|
+
.drawer-heading h2 { min-width: 0 }
|
|
78
|
+
.drawer-tools { display: flex; align-items: center; gap: 8px; flex-shrink: 0 }
|
|
79
|
+
.drawer-tools:has(> span:empty) { gap: 0 }
|
|
80
|
+
.link-button.primary { font-weight: 600; background: var(--tint); border-color: #eabda0; white-space: nowrap }
|
|
81
|
+
.link-button.primary:hover { background: #ffe9d6 }
|
|
82
|
+
/* Notes only appear when something is off; each stays one compact line. */
|
|
83
|
+
.drawer-content > .warning { font-size: 12px; margin: 0 0 8px; padding: 6px 10px }
|
|
84
|
+
.drawer-content > details.warning { background: #fff9e8; border-color: #eed79d }
|
|
85
|
+
.drawer-content > details.warning summary { font-size: 12px; color: #804810 }
|
|
86
|
+
.note-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px }
|
|
87
|
+
.note-row button { font-size: 12px; padding: 1px 8px }
|
|
74
88
|
.link-button { display: inline-block; border: 1px solid var(--line); border-radius: 6px; background: white; padding: 4px 10px; font-size: 12px; color: var(--accent); text-decoration: none }
|
|
75
89
|
.link-button:hover { background: var(--tint); border-color: #eabda0 }
|
|
76
90
|
.drawer-content details.detail-section { padding: 8px 12px }
|
|
@@ -100,10 +114,15 @@ button.category-tag:hover { background: #ffe8d2 }
|
|
|
100
114
|
@media (max-width: 800px) {
|
|
101
115
|
/* The drawer is a bottom sheet here, so it rises instead (reduced motion still zeroes the duration). */
|
|
102
116
|
.drawer:not([hidden]) { animation-name: sheet-in }
|
|
117
|
+
/* A full Session ID needs the whole sheet width: the buttons drop onto their own row instead of squeezing it. */
|
|
118
|
+
.drawer-header { flex-wrap: wrap; row-gap: 8px }
|
|
119
|
+
.drawer-heading { flex: 1 1 100% }
|
|
120
|
+
.drawer-heading h2 { font-size: 14px }
|
|
121
|
+
.drawer-tools { margin-left: auto }
|
|
103
122
|
.dash-grid { grid-template-columns: 1fr }
|
|
104
123
|
/* Search wraps under the tabs here, so the tab line moves onto the tab row itself. */
|
|
105
124
|
.dash-controls { border-bottom: 0 }
|
|
106
125
|
.view-tabs { flex-basis: 100%; border-bottom: 1px solid var(--line) }
|
|
107
126
|
.dash-controls .search-label { max-width: none; margin-left: 0 }
|
|
108
|
-
.dash-controls .search-label, #source-choice { margin-bottom: 0 }
|
|
127
|
+
.dash-controls .search-label, .dash-controls .project-choice, #source-choice { margin-bottom: 0 }
|
|
109
128
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Project-wide dashboard over every archived session, written to ``.atk/traces/index.html``.
|
|
2
2
|
|
|
3
|
-
The page only summarizes: identity,
|
|
3
|
+
The page only summarizes: identity, actual progress and category per issue, whether the latest detection finished, plus a link into each session's own
|
|
4
4
|
preview. It reads saved records through ``records.status`` (which already verifies evidence digests) and never opens
|
|
5
5
|
raw trace bodies, so it stays small and fast. A damaged session or issue is reported on its own entry and cannot hide
|
|
6
6
|
the healthy ones.
|
|
@@ -45,12 +45,6 @@ def _text(value, limit=TEXT_LIMIT):
|
|
|
45
45
|
return value if len(value) <= limit else value[: limit - 1] + "…"
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def _texts(value):
|
|
49
|
-
if not isinstance(value, list):
|
|
50
|
-
return []
|
|
51
|
-
return [text for text in (_text(item, ITEM_LIMIT) for item in value[:LIST_LIMIT]) if text]
|
|
52
|
-
|
|
53
|
-
|
|
54
48
|
def _ms(seconds):
|
|
55
49
|
return None if seconds is None else int(seconds * 1000)
|
|
56
50
|
|
|
@@ -143,8 +137,6 @@ def _session_entry(session_dir):
|
|
|
143
137
|
)
|
|
144
138
|
return entry
|
|
145
139
|
session = status["session"]
|
|
146
|
-
archive = session.get("archive") if isinstance(session.get("archive"), dict) else {}
|
|
147
|
-
completeness = archive.get("completeness") if isinstance(archive.get("completeness"), dict) else {}
|
|
148
140
|
detections = [item for item in session.get("detections", []) if isinstance(item, dict)]
|
|
149
141
|
issues, issue_stamps = _issue_entries(session_dir, status)
|
|
150
142
|
archived = parse_instant(session.get("created_at"))
|
|
@@ -153,31 +145,14 @@ def _session_entry(session_dir):
|
|
|
153
145
|
registry = session_dir.parent / "projects.json"
|
|
154
146
|
if registry.is_file():
|
|
155
147
|
updated = max(updated or 0, registry.stat().st_mtime)
|
|
148
|
+
# The drawer is a preview: it only needs to say whether the issue list can be trusted. Scale, capture coverage,
|
|
149
|
+
# focus and gap details stay on the session page, which shows every detection in full.
|
|
156
150
|
last = detections[-1] if detections else None
|
|
157
|
-
scope = last.get("scope") if last and isinstance(last.get("scope"), dict) else {}
|
|
158
|
-
traces, observations = completeness.get("trace_count"), completeness.get("observation_count")
|
|
159
151
|
entry.update(
|
|
160
152
|
session_id=session["session_id"],
|
|
161
153
|
source={key: _text(session.get("source", {}).get(key), ITEM_LIMIT) for key in SAFE_SOURCE_FIELDS},
|
|
162
|
-
archived_ms=_ms(archived),
|
|
163
154
|
updated_ms=_ms(updated),
|
|
164
|
-
|
|
165
|
-
observations=observations if type(observations) is int else None,
|
|
166
|
-
files=len(archive["files"]) if isinstance(archive.get("files"), list) else len(session.get("captures", [])),
|
|
167
|
-
capture={
|
|
168
|
-
"status": _text(archive.get("status"), 40),
|
|
169
|
-
"completeness": _text(completeness.get("status"), 40),
|
|
170
|
-
"gaps": _texts(completeness.get("gaps")),
|
|
171
|
-
},
|
|
172
|
-
detection=(
|
|
173
|
-
{
|
|
174
|
-
"status": _text(last.get("status"), 40),
|
|
175
|
-
"focus": _text(scope.get("focus")),
|
|
176
|
-
"gaps": _texts(last.get("gaps")),
|
|
177
|
-
}
|
|
178
|
-
if last
|
|
179
|
-
else None
|
|
180
|
-
),
|
|
155
|
+
detection={"status": _text(last.get("status"), 40)} if last else None,
|
|
181
156
|
issues=issues,
|
|
182
157
|
problems=[_problem(item) for item in status["warnings"][:LIST_LIMIT]],
|
|
183
158
|
problem_count=len(status["warnings"]),
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
| `3a735b2`:`records.py` 新增 `change_summary`、`verification_summary` 校验 | 大盘只在 `prepare_issue()` 增加 `category` 校验,不在同一函数 | 无冲突 |
|
|
52
52
|
| `3a735b2`:`styles.css` 新增 `.stage-record`、`.change-item`、`.source-file` | 属于单会话页专用样式 | 抽取共享样式时留在 `trace/styles.css`,不进入 `base.css` |
|
|
53
53
|
| `records.status()` 读取全部 Issue、改动和验证,并校验引用哈希;在 Magic 6 个会话上逐个调用,合计约 0.3 秒 | 大盘可以直接复用,不必另写读取逻辑 | 大盘数据构建基于 `status()` |
|
|
54
|
-
| Magic 本地导入的 `archive.completeness` 有 `trace_count`、`observation_count
|
|
54
|
+
| Magic 本地导入的 `archive.completeness` 有 `trace_count`、`observation_count`;其他来源不一定有。本地导入的完整性固定为“部分” | 规模和完整性在会话之间没有区分度,对预览没有帮助 | 大盘不展示,也不输出这些字段(2026-11-10 起);完整内容在会话页「会话信息」中 |
|
|
55
55
|
| 全量测试 `uv run --frozen pytest`:407 通过。不加 `--frozen` 时,本机 uv 会把 `uv.lock` 的 registry 改写为带末尾斜杠,导致 `test_release_scripts.py` 的地址比对失败 | 开发中跑测试可能顺带改动 `uv.lock` | 开发与验收一律使用 `uv run --frozen`,不提交 `uv.lock` |
|
|
56
56
|
|
|
57
57
|
## 4. 数据契约
|
|
@@ -201,16 +201,26 @@
|
|
|
201
201
|
点击卡片打开**会话抽屉**:
|
|
202
202
|
|
|
203
203
|
```text
|
|
204
|
-
┃ SES_2118585447553830912 ⧉
|
|
205
|
-
┃
|
|
206
|
-
┃
|
|
207
|
-
┃ ─ 问题 11 ──────────────────────────────────────────────────── ┃
|
|
204
|
+
┃ SES_2118585447553830912 ⧉ [打开会话页 ↗] [关闭 ×] ┃
|
|
205
|
+
┃ ⚠ 最近一次检测部分完成,问题可能不全;检测缺口见会话页「会话信息」 ┃
|
|
206
|
+
┃ ─ 问题 9 ───────────────────────────────────────────────────── ┃
|
|
208
207
|
┃ ● 002 交付回复把列表项内边距误报为统一 16 未分类 待诊断 ↗ ┃
|
|
209
208
|
┃ ● 001 订单详情空态提示点击选单,但页面没有… 未分类 已诊断 ↗ ┃
|
|
210
209
|
```
|
|
211
210
|
|
|
212
|
-
-
|
|
213
|
-
|
|
211
|
+
抽屉是进入会话页之前的预览,只回答两件事:这份问题列表能不能信,以及下一步要做什么(2026-11-10 起)。
|
|
212
|
+
|
|
213
|
+
- 头部只有完整 Session ID、复制图标、主按钮“打开会话页”和关闭。会话记录不可读取时没有“打开会话页”。
|
|
214
|
+
- 标题下方的提醒只在需要时出现,每条一行;全部正常时不显示,标题下方直接是问题列表:
|
|
215
|
+
|
|
216
|
+
| 条件 | 提醒 |
|
|
217
|
+
|---|---|
|
|
218
|
+
| 最近一次检测不是“已完成” | 最近一次检测{状态},问题可能不全;检测缺口见会话页「会话信息」 |
|
|
219
|
+
| 没有检测记录 | 尚未检测,问题列表为空不代表会话没有问题 |
|
|
220
|
+
| 有记录读取失败 | N 条记录读取失败(可展开明细) |
|
|
221
|
+
| 会话页缺失或过期 | 会话页尚未生成或已过期,附“复制生成命令 / 复制刷新命令”按钮 |
|
|
222
|
+
|
|
223
|
+
- 不展示来源、实例和项目 ID、Trace/观测数、归档和更新时间、关注点、检测与采集缺口:卡片上已有来源和更新时间,其余内容在会话页「会话信息」中完整展示。数据层只输出最近一次检测的 `status`。
|
|
214
224
|
- 问题列表每行:进度点、编号、单行标题(悬停显示全文)、分类、进度、↗ 跳转。按进度排序,待处理的在前,同一进度内按编号。
|
|
215
225
|
|
|
216
226
|
### 7.3 异常维度
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
## 1. 结论与已确认决策
|
|
6
6
|
|
|
7
|
+
会话包含异常,具体异常关联项目。会话和异常分类均不保存独立项目归属,也不保存异常项目的并集。`source.project` 是轨迹来源命名空间,保持原义。项目多选使用可展开的复选菜单,提供清空、已选数量与键盘操作。
|
|
8
|
+
|
|
7
9
|
在现有 Trace 流程内增加工程目录、Issue 的多工程归因,以及大盘和会话页的根因项目展示与筛选。初始化建立可复用的工程边界,诊断按证据决定归因;项目发现本身不产生归因。页面首先回答“问题出在哪个项目”,修复详情再说明“在哪里修改、为什么这样改”。
|
|
8
10
|
|
|
9
11
|
| 决策 | 约定 | 来源 |
|
|
@@ -85,7 +87,7 @@ atk trace project --data <entry.json> --project-root <workspace> --json
|
|
|
85
87
|
|
|
86
88
|
| 信息 | 表达的事实 | 呈现位置 |
|
|
87
89
|
| --- | --- | --- |
|
|
88
|
-
| 根因项目 | 根因实现/规则属于哪个工程;未证实的判断标为待确认 |
|
|
90
|
+
| 根因项目 | 根因实现/规则属于哪个工程;未证实的判断标为待确认 | 异常视图、问题列表及诊断详情 |
|
|
89
91
|
| 修改位置与范围 | 计划或实际在哪个工程、哪些文件/行为上修复;与根因项目不同时说明原因 | 修复方案、实际改动与验证详情 |
|
|
90
92
|
|
|
91
93
|
一条异常可以有多个根因项目,不强制选一个“主责任项目”。通常在根因项目内修改,不需要额外展示一组相同的“改进项目”标签。若权衡后选择其他项目修改,修复详情用一句话说明目标和理由;不能因为修复落在其他项目就改变根因归属。根因未知但已有可行防护方案时,可以记录该方案,根因仍保持未确定。
|
|
@@ -150,7 +152,7 @@ $atk-trace-diagnose 调查 <session-id>,优先检查 APE 和 OT,
|
|
|
150
152
|
|
|
151
153
|
### 大盘
|
|
152
154
|
|
|
153
|
-
|
|
155
|
+
继续提供“会话/异常分类”两个视图,只增加“根因项目”多选。异常分类汇总和问题行的项目标签都来自具体异常的根因归属;不出现“角色”“改进项目”控件,不新增按修改项目筛选或统计的入口。新增的工程名称/别名搜索索引也只取根因关联,通用标题等文本搜索沿用现有行为。沿用现有组件、样式与离线页面,不新增 UI 依赖。
|
|
154
156
|
|
|
155
157
|
```text
|
|
156
158
|
根因项目:[APE ×] [OT ×] 来源:[全部 ▾]
|
|
@@ -161,17 +163,17 @@ ISSUE-001 ……异常标题……
|
|
|
161
163
|
```
|
|
162
164
|
|
|
163
165
|
- 异常抽屉中的每条问题只显示根因项目标签;项目较多时展示前几个和 `+N`,展开可看全。已获支持的根因直接显示项目名,候选根因附“待确认”,不额外排列内部类型与证据状态标签。
|
|
164
|
-
-
|
|
166
|
+
- 分类卡片显示“该类异常涉及的根因项目”及去重问题数;会话卡片仅显示会话事实、异常数量与进度,不展示项目归属。拟修改或实际修改的其他项目不混入这些标签与统计。
|
|
165
167
|
- 多选根因项目使用 OR,与来源、搜索和进度使用 AND。候选根因也可被其项目筛选命中,但始终标明待确认。仅有“APE 根因、OT 修改”的问题只能被 APE 项目筛选命中;选 OT 不能因为修改位置在 OT 就命中。
|
|
166
168
|
- 层级筛选默认包含所选工程及其子工程,并显示“含子项目”。父级用于筛选分组,不向 Issue 自动补写父级归因。
|
|
167
169
|
- 保留“待归因”入口,涵盖尚未记录根因项目的问题,包括已有修复建议但根因仍未知的问题。已证实原因在登记工程以外时,在详情明确说明,不能以修改项目补齐归属。没有问题的会话在未筛选视图继续可见,不推断其根因工程。
|
|
168
170
|
- 当前筛选的问题数、会话数和列表保持一致。进度图例按当前根因项目/来源/搜索范围计算各进度数量,点击图例再过滤列表,避免选中一档后其他档消失。
|
|
169
171
|
- 计数以当前归档内的会话身份加 Issue ID 去重。一条异常命中多个根因项目也只计一次;各工程分项之和可以大于总问题数,不能直接相加为总计。内部存在改进关联不影响项目统计。
|
|
170
|
-
- 根因项目选择与现有抽屉定位写入 URL hash,例如 `#view=category&project=asset-protocol-engine
|
|
172
|
+
- 根因项目选择与现有抽屉定位写入 URL hash,例如 `#view=category&project=asset-protocol-engine`;多个根因项目用重复参数。异常视图保留项目筛选,切回会话总览不受项目条件影响;旧的会话项目筛选链接转入异常视图,明确指定会话的链接保留会话定位,不引入角色参数。
|
|
171
173
|
|
|
172
174
|
### 会话页
|
|
173
175
|
|
|
174
|
-
-
|
|
176
|
+
- 会话概览只显示会话事实;根因项目标签与筛选仅位于内部异常列表,不影响原始轨迹与证据。
|
|
175
177
|
- 左侧问题卡片与问题详情摘要使用同一套根因项目标签,详情可查看归因依据和源码入口,不并列展示一份“改进项目”清单。
|
|
176
178
|
- 修复方案及实际改动沿用已有阶段摘要,按项目说明拟修改/实际修改的位置和范围。修改就在根因项目内时正常展示文件与改动,不重复强调两种项目身份;修改在其他项目时写清“在 OT 的某个 Skill 修改,因为……”,同时说明该方案的作用与限制。提议与已执行改动保持区分。
|
|
177
179
|
- 诊断记录展示自己的历史项目快照,明确区别于 Issue 当前关联,不把旧诊断显示成最新判断。
|
|
@@ -218,12 +220,12 @@ ISSUE-001 ……异常标题……
|
|
|
218
220
|
| --- | --- | --- |
|
|
219
221
|
| 1. 工程目录和关联记录 | 新增 `traces/projects.py`;修改 `cli/trace.py`、`traces/records.py`、`traces/archive.py` | 复用现有路径/锁/原子写/revision 工具;增加 `projects.json` 保留文件名,防止 Session ID 与其冲突;诊断快照及并发核对、修复/验证摘要的项目引用同步覆盖新字段 |
|
|
220
222
|
| 2. Skill 流程与契约 | init、detect、diagnose、optimize、verify、visualize-trace;`docs/trace-tuning.md` 及中英文 README | 初始化阅读既有规则与名称、按项目优先诊断、按项目明确调查/修改范围、记录更新、跨仓候选与加载证据、页面刷新;capture 的来源身份与采集逻辑无须扩张 |
|
|
221
|
-
| 3. 展示与回归 | `visualize/trace.py`、`visualize/traces.py`、两套页面 assets 和相关 tests |
|
|
223
|
+
| 3. 展示与回归 | `visualize/trace.py`、`visualize/traces.py`、两套页面 assets 和相关 tests | 共享根因项目读取/校验及命名结果;异常根因标签、筛选、去重、深链、历史快照、修复详情中的修改范围与取舍、过期提示与可访问性一起验收,不增加角色或修改项目筛选 |
|
|
222
224
|
|
|
223
225
|
关键验收场景:
|
|
224
226
|
|
|
225
227
|
1. 普通单仓、显式普通目录、多 submodule 和嵌套 submodule 均可登记;缺失 checkout 仍可展示边界。重跑保留人工字段,路径/别名歧义可见,父级循环及越界路径拒绝。
|
|
226
|
-
2. 同一 Issue 根因在 APE、可在 APE 或 OT
|
|
228
|
+
2. 同一 Issue 根因在 APE、可在 APE 或 OT 修改:大盘异常视图和会话内异常列表只显示 APE 根因标签,APE 项目筛选命中、OT 项目筛选不命中。只有 OT 也有独立的归因依据时才增加其根因标签,待确认者必须明确标注;命中多个根因或父级时不重复计数。只有修改建议而无根因归属时仍显示待归因。
|
|
227
229
|
3. 指定 APE/OT 后,若证据指向其他登记工程,调查继续并保存依据;仅出现工程名、调用传播或当前源码缺陷不足以确认历史根因。
|
|
228
230
|
4. 修订关联保留 history;省略保留、空数组清空;已保存诊断和采用的哈希不变;并发 revision 冲突不能错配正文与关联。
|
|
229
231
|
5. 未关联、停用/改名/移动工程、目录损坏、零问题会话及旧归档仍可浏览。新保留文件名不会与新会话目录冲突,旧同名会话仍可读取并报告迁移缺口;源码链接维持边界检查。
|