agent-tune-kit 2.3.5__tar.gz → 2.4.0__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.5 → agent_tune_kit-2.4.0}/.codex-plugin/plugin.json +1 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/PKG-INFO +3 -3
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/README.en.md +2 -2
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/README.md +2 -2
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/__init__.py +1 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/projects.py +74 -18
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/records.py +3 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/shared/base.css +3 -11
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/app.js +63 -42
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/page.html +1 -2
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/styles.css +8 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/traces/app.js +116 -62
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/traces/page.html +1 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/traces/styles.css +13 -4
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/trace.py +11 -6
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/traces.py +50 -30
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/trace-dashboard-design.md +16 -14
- agent_tune_kit-2.4.0/docs/trace-project-attribution-design.md +99 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/trace-tuning.md +13 -10
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/pyproject.toml +1 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/validate_skill_pack.py +1 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-trace-detect/SKILL.md +5 -3
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-trace-diagnose/SKILL.md +13 -11
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-trace-init/SKILL.md +4 -2
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-trace-optimize/SKILL.md +5 -3
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-trace-verify/SKILL.md +4 -2
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-visualize-trace/SKILL.md +4 -2
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_install_plugin.py +1 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_release_scripts.py +1 -1
- agent_tune_kit-2.4.0/tests/test_trace_projects.py +147 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_visualize_trace.py +3 -1
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_visualize_traces.py +32 -6
- agent_tune_kit-2.4.0/tests/trace-controls.cjs +54 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-dashboard.cjs +134 -58
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-issue-cards.cjs +4 -4
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-projects.cjs +81 -71
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-stage-cards.cjs +10 -0
- agent_tune_kit-2.3.5/agent_tune_kit/visualize/assets/shared/project-menu.js +0 -32
- agent_tune_kit-2.3.5/docs/trace-project-attribution-design.md +0 -246
- agent_tune_kit-2.3.5/tests/test_trace_projects.py +0 -65
- agent_tune_kit-2.3.5/tests/trace-controls.cjs +0 -86
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/.gitignore +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/__main__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/dataset.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/evaluation.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/main.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/output.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/results.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/trace.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/visualize.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/prepare.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/truth.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/updates.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/validation.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/errors.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/calibration.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/logs.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/rules.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/runner.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/runtime.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/tracing.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/installer.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/results/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/results/assessment.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/results/evidence.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/results/judgments.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/results/summary.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/results/versions.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/archive.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/capture.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/categories.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/langfuse.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/migrate.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/progress.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/query.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/segments.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/store.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/utils/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/utils/csv_io.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/utils/files.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/app.js +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/page.html +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/styles.css +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/vendor/echarts.min.js +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/failures/app.js +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/failures/page.html +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/failures/styles.css +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/lanes.js +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/vendor/markdown-it.LICENSE +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/vendor/markdown-it.min.js +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/dataset.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/failures.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/fields.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/history.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/render.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/timeline.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/workspace.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/assets/agent_tune_kit_evaluation.png +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/assets/agent_tune_kit_trace.png +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/assets/arch-en.png +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/assets/arch.png +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/assets/architecture.en.svg +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/assets/architecture.svg +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/ato-atk-project-boundary-recommendation-2026-11-05.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/cli-skill-modularization-plan.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/codex_agent_tuning_prd.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/execution-evidence-and-tracing-plan.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/ground-truth-and-grading-assessment-2026-10-25.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/local-context.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/shared-versioning-and-confirmation.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/skill-template-pack-usage.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/surginame-atk-capability-review-2026-10-27.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/trace-change-verification-readability-diagnosis.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/trace-swimlane-design.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/trace-tuning-validation.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/docs/truth-and-assessment.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/check-release.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/dev-refresh-install.sh +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/install_plugin.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/publish-pypi.sh +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/publish-release.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/release-version.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/scripts/release-version.sh +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-dataset/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-dataset/scripts/update_dataset.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-diagnose/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-eval/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-init/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-optimize/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-report/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-trace-capture/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-visualize-dataset/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-visualize-dataset/scripts/generate_dataset_browser.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-visualize-failures/SKILL.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/skills/atk-visualize-failures/scripts/generate_failure_browser.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/templates/.atk/runner/eval_runner.py.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/templates/.atk/runner/failure_rule.py.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/templates/.atk/runner/import_evidence.py.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/templates/.gitkeep +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/__init__.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/conftest.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/fixtures/legacy_eval_runner.py.txt +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/fixtures/managed_v1.py.md +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_assessment_contract.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_atk_init_contract.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_cli_workflow.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_dataset_updates.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_diagnosis.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_evidence_import.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_evidence_judgments.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_evidence_packaging.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_evidence_versions.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_execution_evidence.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_execution_outcomes.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_execution_tracing.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_generate_dataset_browser.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_generate_failure_browser.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_judge_calibration.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_local_context.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_plugin_cache.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_runner_output_columns.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_runner_template_row_logging.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_runtime_contracts.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_snapshot_reads.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_capture.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_categories.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_cli.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_event_list.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_langfuse.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_progress.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_query.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_records.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_scroll_layout.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_segments.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_trace_store.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_truth_browser.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_truth_cli.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_truth_contract.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_truth_runner.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/test_v2_progress.py +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-event-detail.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-event-layout.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-event-list.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-event-wheel.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-fragments.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-preview-scroll.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-scroll-layout.cjs +0 -0
- {agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/tests/trace-selection-reason.cjs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-tune-kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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
|
+
Version: 2.4.0
|
|
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
|
|
@@ -196,6 +196,6 @@ Each session archive is stored under `.atk/traces/<session_id>/` in your Agent p
|
|
|
196
196
|
|
|
197
197
|
[Trace tuning guide for source configuration, supported formats, and archive layout](docs/trace-tuning.md)
|
|
198
198
|
|
|
199
|
-
[Multi-project attribution and filtering
|
|
199
|
+
[Multi-project attribution and filtering details (Chinese)](docs/trace-project-attribution-design.md)
|
|
200
200
|
|
|
201
|
-
Use `atk trace project` to register workspace projects and submodules.
|
|
201
|
+
Use `atk trace project` to register workspace projects and submodules. Record associated projects with reasonable causal explanations for human review, and filter them in the dashboard and session issue list. Associations do not require a completed or verified fix; reasons describe uncertainty, and repair details describe modification locations.
|
|
@@ -182,6 +182,6 @@ Each session archive is stored under `.atk/traces/<session_id>/` in your Agent p
|
|
|
182
182
|
|
|
183
183
|
[Trace tuning guide for source configuration, supported formats, and archive layout](docs/trace-tuning.md)
|
|
184
184
|
|
|
185
|
-
[Multi-project attribution and filtering
|
|
185
|
+
[Multi-project attribution and filtering details (Chinese)](docs/trace-project-attribution-design.md)
|
|
186
186
|
|
|
187
|
-
Use `atk trace project` to register workspace projects and submodules.
|
|
187
|
+
Use `atk trace project` to register workspace projects and submodules. Record associated projects with reasonable causal explanations for human review, and filter them in the dashboard and session issue list. Associations do not require a completed or verified fix; reasons describe uncertainty, and repair details describe modification locations.
|
|
@@ -182,6 +182,6 @@ $atk-trace-verify 验证 <session-id> 的 ISSUE-001 对应候选,并检查相
|
|
|
182
182
|
|
|
183
183
|
[轨迹调优指南,包含来源配置、支持格式和归档结构](docs/trace-tuning.md)
|
|
184
184
|
|
|
185
|
-
[
|
|
185
|
+
[多工程关联与项目筛选说明](docs/trace-project-attribution-design.md)
|
|
186
186
|
|
|
187
|
-
支持通过 `atk trace project`
|
|
187
|
+
支持通过 `atk trace project` 登记工作区及子模块;诊断按合理的原因解释记录“关联项目”,供人工审核,大盘与会话问题栏均可筛选。关联不以修复完成或验证通过为前提;不确定性写在关联理由中,修改位置在修复详情中说明。
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Workspace project registry and
|
|
1
|
+
"""Workspace project registry and issue associations for human review."""
|
|
2
2
|
|
|
3
3
|
import configparser
|
|
4
4
|
import hashlib
|
|
@@ -150,14 +150,12 @@ def validate_links(session_dir, links):
|
|
|
150
150
|
projects = project_map(Path(session_dir).parent)
|
|
151
151
|
seen = set()
|
|
152
152
|
for link in links:
|
|
153
|
-
if not isinstance(link, dict):
|
|
153
|
+
if not isinstance(link, dict) or set(link) - {"project_id", "reason", "evidence", "source_paths"}:
|
|
154
154
|
raise UserActionRequired("Invalid project link.")
|
|
155
|
-
key =
|
|
156
|
-
if not
|
|
155
|
+
key = link.get("project_id")
|
|
156
|
+
if not isinstance(key, str) or key not in projects or key in seen:
|
|
157
157
|
raise UserActionRequired("Unknown or duplicate project link.")
|
|
158
158
|
seen.add(key)
|
|
159
|
-
if key[1] not in {"root_cause", "improvement"} or link.get("evidence_state") not in {"hypothesis", "supported"}:
|
|
160
|
-
raise UserActionRequired("Invalid project attribution state.")
|
|
161
159
|
if (
|
|
162
160
|
not isinstance(link.get("reason"), str)
|
|
163
161
|
or not link["reason"].strip()
|
|
@@ -176,26 +174,84 @@ def validate_links(session_dir, links):
|
|
|
176
174
|
return links
|
|
177
175
|
|
|
178
176
|
|
|
179
|
-
def
|
|
180
|
-
|
|
177
|
+
def _display_name(entry, project_id):
|
|
178
|
+
return entry.get("abbreviation") or entry.get("name") or project_id
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def linked_projects(root, issue, projects=None):
|
|
182
|
+
"""Return the display identity of each project an issue links to, once per project.
|
|
183
|
+
|
|
184
|
+
Pages only need the stable ID, the shown name and aliases for search; the rest of the registry stays out of them.
|
|
185
|
+
Pass ``projects`` (from ``project_map``) when resolving many issues so the registry is read once.
|
|
186
|
+
"""
|
|
187
|
+
projects = project_map(root) if projects is None else projects
|
|
181
188
|
result = []
|
|
182
189
|
links = issue.get("project_links", [])
|
|
183
190
|
if not isinstance(links, list):
|
|
184
191
|
return result
|
|
192
|
+
seen = set()
|
|
185
193
|
for link in links:
|
|
186
|
-
if (
|
|
187
|
-
not isinstance(link, dict)
|
|
188
|
-
or not isinstance(link.get("project_id"), str)
|
|
189
|
-
or link.get("role") != "root_cause"
|
|
190
|
-
):
|
|
194
|
+
if not isinstance(link, dict) or not isinstance(link.get("project_id"), str) or link["project_id"] in seen:
|
|
191
195
|
continue
|
|
192
|
-
|
|
196
|
+
project_id = link["project_id"]
|
|
197
|
+
seen.add(project_id)
|
|
198
|
+
entry = projects.get(project_id, {})
|
|
199
|
+
aliases = entry.get("aliases")
|
|
200
|
+
result.append(
|
|
201
|
+
{
|
|
202
|
+
"id": project_id,
|
|
203
|
+
"name": _display_name(entry, project_id),
|
|
204
|
+
"aliases": [alias for alias in aliases if isinstance(alias, str)] if isinstance(aliases, list) else [],
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
return result
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def project_index(root, linked, projects=None):
|
|
211
|
+
"""Summarize the projects that issues actually link to, for the pages' single-choice project filter.
|
|
212
|
+
|
|
213
|
+
``linked`` yields ``(session_key, linked_projects)`` per issue. Registered projects without any linked issue are
|
|
214
|
+
left out: nothing could be found by choosing them. A linked ID missing from the registry stays in, shown by its ID,
|
|
215
|
+
so its issues remain reachable. Counts are per project; an issue linked to several projects counts once in each,
|
|
216
|
+
so the entries must not be added up as an issue total.
|
|
217
|
+
"""
|
|
218
|
+
projects = project_map(root) if projects is None else projects
|
|
219
|
+
found = {}
|
|
220
|
+
for session, items in linked:
|
|
221
|
+
for item in items:
|
|
222
|
+
entry = found.setdefault(
|
|
223
|
+
item["id"], {"id": item["id"], "name": item["name"], "issues": 0, "sessions": set()}
|
|
224
|
+
)
|
|
225
|
+
entry["issues"] += 1
|
|
226
|
+
entry["sessions"].add(session)
|
|
227
|
+
names = {}
|
|
228
|
+
for entry in found.values():
|
|
229
|
+
names.setdefault(entry["name"], []).append(entry["id"])
|
|
230
|
+
result = []
|
|
231
|
+
for entry in found.values():
|
|
232
|
+
registered = projects.get(entry["id"])
|
|
233
|
+
name = entry["name"]
|
|
234
|
+
if len(names[name]) > 1:
|
|
235
|
+
# Two projects share an abbreviation: tell the filter's choices apart by where each one lives.
|
|
236
|
+
tail = Path(registered["path"]).name if registered and registered.get("path") else entry["id"]
|
|
237
|
+
name = f"{name} · {tail or entry['id']}"
|
|
193
238
|
result.append(
|
|
194
239
|
{
|
|
195
|
-
|
|
196
|
-
"
|
|
197
|
-
"
|
|
198
|
-
"
|
|
240
|
+
"id": entry["id"],
|
|
241
|
+
"name": name,
|
|
242
|
+
"issues": entry["issues"],
|
|
243
|
+
"sessions": len(entry["sessions"]),
|
|
244
|
+
"registered": registered is not None,
|
|
245
|
+
"deprecated": bool(registered and registered.get("deprecated") is True),
|
|
199
246
|
}
|
|
200
247
|
)
|
|
248
|
+
result.sort(
|
|
249
|
+
key=lambda item: (
|
|
250
|
+
item["deprecated"],
|
|
251
|
+
not item["registered"],
|
|
252
|
+
-item["issues"],
|
|
253
|
+
item["name"].casefold(),
|
|
254
|
+
item["id"],
|
|
255
|
+
)
|
|
256
|
+
)
|
|
201
257
|
return result
|
|
@@ -172,6 +172,7 @@ def prepare_issue(session_dir, data, *, dry_run=False):
|
|
|
172
172
|
"created_at": now(),
|
|
173
173
|
"status": "open",
|
|
174
174
|
"segments": [],
|
|
175
|
+
"project_links": [],
|
|
175
176
|
}
|
|
176
177
|
)
|
|
177
178
|
if "project_links" in data:
|
|
@@ -347,9 +348,10 @@ def save_diagnosis(session_dir, issue_id, text, diagnosis_id=None, expected_revi
|
|
|
347
348
|
"description": issue["description"],
|
|
348
349
|
"evidence": issue["evidence"],
|
|
349
350
|
"segments": issue.get("segments", []),
|
|
351
|
+
"project_links": validate_links(directory, issue.get("project_links", [])),
|
|
350
352
|
"created_at": now(),
|
|
351
353
|
}
|
|
352
|
-
for optional in ("selection_reason", "category"
|
|
354
|
+
for optional in ("selection_reason", "category"):
|
|
353
355
|
if optional in issue:
|
|
354
356
|
snapshot[optional] = issue[optional]
|
|
355
357
|
if issue.get("project_links"):
|
{agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/shared/base.css
RENAMED
|
@@ -63,15 +63,15 @@ h3 { font-size: 14px }
|
|
|
63
63
|
.progress-dot.excluded { background: transparent; box-shadow: inset 0 0 0 1.5px var(--p-pending) }
|
|
64
64
|
.category-tag { display: inline-block; max-width: 100%; background: #fff8f1; color: var(--accent); font-size: 11px; line-height: 1.5; padding: 2px 6px; border-radius: 4px; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
65
65
|
a.category-tag:hover { background: #ffe8d2 }
|
|
66
|
-
input:not([type=checkbox]), select
|
|
66
|
+
input:not([type=checkbox]), select {
|
|
67
67
|
display: block; height: var(--control-height); min-width: 0; max-width: 100%; padding: 0 11px;
|
|
68
68
|
font-size: 13px; line-height: normal; border-color: #cdd8e1;
|
|
69
69
|
}
|
|
70
|
-
select
|
|
70
|
+
select {
|
|
71
71
|
appearance: none; padding-right: 32px; text-overflow: ellipsis;
|
|
72
72
|
background: white url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e") no-repeat right 11px center / 14px;
|
|
73
73
|
}
|
|
74
|
-
input:not([type=checkbox]):hover, select:hover
|
|
74
|
+
input:not([type=checkbox]):hover, select:hover { border-color: #9baebb }
|
|
75
75
|
input[type=checkbox] { width: 16px; height: 16px; margin: 0; padding: 0; flex-shrink: 0; accent-color: var(--brand) }
|
|
76
76
|
@media (forced-colors: active) {
|
|
77
77
|
select { appearance: auto; background-image: none; padding-right: 8px }
|
|
@@ -96,11 +96,3 @@ input[type=checkbox] { width: 16px; height: 16px; margin: 0; padding: 0; flex-sh
|
|
|
96
96
|
.drawer-resizer { display: none }
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
/* Project attribution belongs to issues; the menu is shared by both issue views. */
|
|
100
|
-
.project-choice { position: relative; min-width: 0; max-width: 100%; margin-bottom: 7px; font-size: 13px }
|
|
101
|
-
.project-choice > summary { line-height: calc(var(--control-height) - 2px); list-style: none; white-space: nowrap; overflow: hidden; border: 1px solid #cdd8e1; border-radius: 6px }
|
|
102
|
-
.project-choice > summary::-webkit-details-marker { display: none }
|
|
103
|
-
.project-choice[open] > summary { border-color: #deb493; color: var(--accent) }
|
|
104
|
-
.project-menu { position: fixed; z-index: 20; width: min(300px, calc(100vw - 16px)); max-height: min(320px, calc(100dvh - 16px)); overflow: auto; overscroll-behavior: contain; padding: 12px; border: 1px solid var(--line); border-radius: 6px; background: white; box-shadow: 0 6px 20px #0002 }
|
|
105
|
-
.project-menu p { margin: 0 0 8px }
|
|
106
|
-
#project-filter label { display: flex; align-items: center; gap: 8px; padding: 6px 0; overflow-wrap: anywhere }
|
|
@@ -23,26 +23,14 @@
|
|
|
23
23
|
const captureById = new Map(data.captures.map(c => [c.id, c]));
|
|
24
24
|
const issueById = new Map(data.issues.map(item => [item.record.id, item]));
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
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(); };
|
|
26
|
+
// One linked project at a time, or every issue. Only projects this session's issues link to are offered.
|
|
27
|
+
const PROJECTS = data.project_index || [];
|
|
28
|
+
const PROJECT = new Map(PROJECTS.map(entry => [entry.id, entry]));
|
|
29
|
+
// Older links may carry several projects or the removed empty-association value: keep the first one still offered.
|
|
30
|
+
const projectFrom = params => params.getAll("project").find(id => PROJECT.has(id)) || "";
|
|
31
|
+
let railProject = projectFrom(new URLSearchParams(location.hash.slice(1)));
|
|
32
|
+
const projectMatches = item => !railProject || (item.linked_projects || []).some(project => project.id === railProject);
|
|
33
|
+
const projectLabel = entry => `${entry.name}${entry.deprecated ? "(已弃用)" : entry.registered === false ? "(未登记)" : ""}`;
|
|
46
34
|
|
|
47
35
|
const filters = ["trace-filter", "type-filter", "trace-search", "record-mode"];
|
|
48
36
|
const list = $("trace-list"), scroller = $("trace-scroll");
|
|
@@ -69,11 +57,11 @@
|
|
|
69
57
|
const dashboardHash = params => `../index.html#${params}`;
|
|
70
58
|
const projectLabels = item => {
|
|
71
59
|
const row = el("p", "关联项目:", "issue-projects");
|
|
72
|
-
const projects = item.
|
|
73
|
-
if (!projects.length) row.append(document.createTextNode("
|
|
60
|
+
const projects = item.linked_projects || [];
|
|
61
|
+
if (!projects.length) row.append(document.createTextNode("无"));
|
|
74
62
|
projects.forEach((project, index) => {
|
|
75
63
|
if (index) row.append(document.createTextNode("、"));
|
|
76
|
-
const name = project.name
|
|
64
|
+
const name = project.name;
|
|
77
65
|
const label = el(data.dashboard.available ? "a" : "span", name);
|
|
78
66
|
if (data.dashboard.available) {
|
|
79
67
|
label.href = dashboardHash(`view=category&project=${encodeURIComponent(project.id)}`);
|
|
@@ -108,7 +96,6 @@
|
|
|
108
96
|
onRoot: index => openEventDrawer(currentCapture.nodes[index], document.activeElement),
|
|
109
97
|
onIssueBadge: track => {
|
|
110
98
|
$("issue-search").value = "";
|
|
111
|
-
$("issue-status").value = "";
|
|
112
99
|
railFilter = {track, ids: data.issues.filter(item => item.fragments.some(part => part.capture_id === currentCapture?.id && part.track === track)).map(item => item.record.id)};
|
|
113
100
|
renderIssueRail();
|
|
114
101
|
},
|
|
@@ -321,6 +308,16 @@
|
|
|
321
308
|
const headings = headingNodes.map(node => node.textContent);
|
|
322
309
|
const structured = headings.join("|") === "问题描述|问题根因|最小修复方案"
|
|
323
310
|
|| headings.join("|") === "Issue description|Root cause|Minimal fix";
|
|
311
|
+
if (snapshot?.project_links) {
|
|
312
|
+
const entries = new Map((snapshot.project_registry?.projects || []).map(p => [p.id, p]));
|
|
313
|
+
const associations = el("div");
|
|
314
|
+
associations.append(el("p", "诊断时的关联项目:" + (snapshot.project_links.length ? "" : "无")));
|
|
315
|
+
for (const link of snapshot.project_links) {
|
|
316
|
+
const entry = entries.get(link.project_id);
|
|
317
|
+
associations.append(el("p", `${entry?.abbreviation || entry?.name || link.project_id}:${link.reason}`));
|
|
318
|
+
}
|
|
319
|
+
body.prepend(associations);
|
|
320
|
+
}
|
|
324
321
|
if (index === 0 && structured) {
|
|
325
322
|
container.append(body);
|
|
326
323
|
continue;
|
|
@@ -335,11 +332,6 @@
|
|
|
335
332
|
container.append(description);
|
|
336
333
|
}
|
|
337
334
|
const details = el("details", undefined, "detail-section");
|
|
338
|
-
if (snapshot?.project_links) {
|
|
339
|
-
const entries = new Map((snapshot.project_registry?.projects || []).map(p => [p.id, p]));
|
|
340
|
-
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" ? "" : "(待确认)"); });
|
|
341
|
-
body.prepend(el("p", `诊断时的关联项目:${names.join("、") || "待归因"}`));
|
|
342
|
-
}
|
|
343
335
|
const name = diagnosis.reference.path.split("/").pop();
|
|
344
336
|
details.append(el("summary", `展开原诊断 · ${name}`), body);
|
|
345
337
|
container.append(details);
|
|
@@ -1116,16 +1108,51 @@
|
|
|
1116
1108
|
if (mine && investigation.index >= 2) card.querySelectorAll(".seg-more").forEach(more => { more.open = true; });
|
|
1117
1109
|
}
|
|
1118
1110
|
}
|
|
1111
|
+
const searchMatches = (item, text) => !text || pretty(item.record).toLocaleLowerCase().includes(text) ||
|
|
1112
|
+
progressOf(item).label.toLocaleLowerCase().includes(text) || (item.linked_projects || []).some(p => [p.name, ...(p.aliases || [])].some(name => name.toLocaleLowerCase().includes(text)));
|
|
1113
|
+
function chooseProject(id) {
|
|
1114
|
+
railProject = railProject === id ? "" : id;
|
|
1115
|
+
syncHash(); renderIssueRail();
|
|
1116
|
+
}
|
|
1117
|
+
// Project counts follow the search only: the lane filter and the chosen project leave every project's real size.
|
|
1118
|
+
function renderProjectChoice(text) {
|
|
1119
|
+
const box = $("project-legend");
|
|
1120
|
+
box.replaceChildren();
|
|
1121
|
+
const issues = data.issues.filter(item => searchMatches(item, text));
|
|
1122
|
+
const counts = new Map();
|
|
1123
|
+
for (const item of issues) for (const project of item.linked_projects || []) {
|
|
1124
|
+
if (PROJECT.has(project.id)) counts.set(project.id, (counts.get(project.id) || 0) + 1);
|
|
1125
|
+
}
|
|
1126
|
+
const order = new Map(PROJECTS.map((entry, index) => [entry.id, index]));
|
|
1127
|
+
const shown = PROJECTS.filter(entry => counts.get(entry.id) || entry.id === railProject).sort((a, b) =>
|
|
1128
|
+
Number(Boolean(a.deprecated)) - Number(Boolean(b.deprecated)) || Number(a.registered === false) - Number(b.registered === false) ||
|
|
1129
|
+
(counts.get(b.id) || 0) - (counts.get(a.id) || 0) || order.get(a.id) - order.get(b.id));
|
|
1130
|
+
// A single project that holds every issue filters nothing, so the row would only repeat the total. This is judged on
|
|
1131
|
+
// the whole session, not the search, so the row does not vanish while typing.
|
|
1132
|
+
box.hidden = !PROJECTS.length || (PROJECTS.length === 1 && !railProject && PROJECTS[0].issues === data.issues.length);
|
|
1133
|
+
if (box.hidden) return;
|
|
1134
|
+
const choice = (name, n, id, title) => {
|
|
1135
|
+
const item = button("", () => chooseProject(id), "project-item");
|
|
1136
|
+
item.setAttribute("role", "radio");
|
|
1137
|
+
item.setAttribute("aria-checked", String(railProject === id));
|
|
1138
|
+
item.title = title;
|
|
1139
|
+
item.append(el("span", name, "project-name"), el("span", String(n), "project-count"));
|
|
1140
|
+
if (!n) item.classList.add("is-empty");
|
|
1141
|
+
return item;
|
|
1142
|
+
};
|
|
1143
|
+
box.append(choice("全部", issues.length, "", "显示全部问题"));
|
|
1144
|
+
for (const entry of shown) {
|
|
1145
|
+
box.append(choice(projectLabel(entry), counts.get(entry.id) || 0, entry.id,
|
|
1146
|
+
railProject === entry.id ? `取消筛选 ${projectLabel(entry)}` : `只看关联 ${projectLabel(entry)} 的问题`));
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1119
1149
|
function renderIssueRail() {
|
|
1120
1150
|
const text = $("issue-search").value.toLocaleLowerCase();
|
|
1121
|
-
|
|
1151
|
+
renderProjectChoice(text);
|
|
1122
1152
|
const filtered = data.issues.filter(item => {
|
|
1123
1153
|
if (!projectMatches(item) && new URLSearchParams(location.hash.slice(1)).get("issue") !== item.record.id) return false;
|
|
1124
1154
|
if (railFilter && !railFilter.ids.includes(item.record.id)) return false;
|
|
1125
|
-
|
|
1126
|
-
if (status && progress !== status) return false;
|
|
1127
|
-
if (!text) return true;
|
|
1128
|
-
return pretty(item.record).toLocaleLowerCase().includes(text) || progress.toLocaleLowerCase().includes(text);
|
|
1155
|
+
return searchMatches(item, text);
|
|
1129
1156
|
});
|
|
1130
1157
|
$("rail-count").textContent = `${filtered.length}/${data.issues.length}`;
|
|
1131
1158
|
const box = $("issue-rail-list"); box.replaceChildren();
|
|
@@ -1206,7 +1233,7 @@
|
|
|
1206
1233
|
syncRailSelection();
|
|
1207
1234
|
}
|
|
1208
1235
|
function syncHash() {
|
|
1209
|
-
const parts =
|
|
1236
|
+
const parts = railProject ? [`project=${encodeURIComponent(railProject)}`] : [];
|
|
1210
1237
|
if (investigation) {
|
|
1211
1238
|
parts.push(`issue=${encodeURIComponent(investigation.item.record.id)}`);
|
|
1212
1239
|
const part = partNow();
|
|
@@ -1223,9 +1250,7 @@
|
|
|
1223
1250
|
if (hash !== location.hash) history.replaceState(null, "", hash || location.pathname + location.search);
|
|
1224
1251
|
const raw = hash.slice(1);
|
|
1225
1252
|
const params = new URLSearchParams(raw.includes("=") ? raw : `issue=${raw}`);
|
|
1226
|
-
|
|
1227
|
-
for (const input of projectInputs) input.checked = projectSelection.has(input.value);
|
|
1228
|
-
updateProjectSummary();
|
|
1253
|
+
railProject = projectFrom(params);
|
|
1229
1254
|
const issueId = params.get("issue");
|
|
1230
1255
|
const seg = params.get("seg");
|
|
1231
1256
|
const event = params.get("event");
|
|
@@ -1262,14 +1287,10 @@
|
|
|
1262
1287
|
$("capture-filter").closest("label").hidden = Boolean(currentCapture?.current);
|
|
1263
1288
|
options($("capture-filter"), data.captures.map(c => c.id));
|
|
1264
1289
|
if (currentCapture) $("capture-filter").value = currentCapture.id;
|
|
1265
|
-
$("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(); };
|
|
1266
1290
|
$("capture-filter").onchange = () => { investigation = null; scopeBefore = null; railFilter = null; chooseCapture(); renderIssueRail(); renderTraces(); };
|
|
1267
1291
|
$("trace-filter").onchange = () => focusTrace(scope());
|
|
1268
1292
|
for (const id of ["trace-search","type-filter","record-mode"]) $(id).addEventListener(id === "trace-search" ? "input" : "change", () => renderTraces());
|
|
1269
|
-
const presentProgress = new Set(data.issues.map(item => item.progress.label));
|
|
1270
|
-
options($("issue-status"), data.progress_legend.map(entry => entry.label).filter(label => presentProgress.has(label)), "全部进度");
|
|
1271
1293
|
$("issue-search").oninput = () => { railFilter = null; renderIssueRail(); };
|
|
1272
|
-
$("issue-status").onchange = () => { railFilter = null; renderIssueRail(); };
|
|
1273
1294
|
const collapsed = localStorage.getItem(RAIL_KEY) === "1";
|
|
1274
1295
|
document.body.classList.toggle("rail-collapsed", collapsed);
|
|
1275
1296
|
$("rail-toggle").setAttribute("aria-expanded", String(!collapsed));
|
{agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/page.html
RENAMED
|
@@ -21,8 +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
|
-
<
|
|
25
|
-
<label><span class="sr-only">状态</span><select id="issue-status"></select></label>
|
|
24
|
+
<div id="project-legend" class="rail-projects" role="radiogroup" aria-label="关联项目" hidden></div>
|
|
26
25
|
</div>
|
|
27
26
|
<div id="issue-rail-list" class="rail-list" tabindex="0" aria-label="问题列表"></div>
|
|
28
27
|
</aside>
|
{agent_tune_kit-2.3.5 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/styles.css
RENAMED
|
@@ -33,7 +33,14 @@ body.rail-collapsed #rail-toggle { transform: rotate(180deg) }
|
|
|
33
33
|
.rail-filters .search-label { flex: 1 0 100%; min-width: 0 }
|
|
34
34
|
.rail-filters > label { min-width: 0; max-width: 100% }
|
|
35
35
|
.rail-filters input[type=search] { width: 100% }
|
|
36
|
-
|
|
36
|
+
/* Project choice: one linked project or all issues; each count is the issues linked to that project. */
|
|
37
|
+
.rail-projects { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 0 100%; min-width: 0 }
|
|
38
|
+
.project-item { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; min-width: 0; padding: 2px 8px; border: 1px solid var(--line); border-radius: 6px; background: white; color: var(--muted); font-size: 12px; line-height: 1.5 }
|
|
39
|
+
.project-item:hover { background: var(--tint) }
|
|
40
|
+
.project-item[aria-checked=true] { background: var(--tint); color: var(--accent); border-color: #eabda0 }
|
|
41
|
+
.project-item .project-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
42
|
+
.project-item .project-count { font-weight: 700 }
|
|
43
|
+
.project-item.is-empty { opacity: .6 }
|
|
37
44
|
.rail-list { flex: 1; min-height: 0; overflow: auto; scrollbar-gutter: stable; scrollbar-width: thin; padding: 12px; display: flex; flex-direction: column; gap: 12px }
|
|
38
45
|
.issue-card { display: flex; flex: none; flex-direction: column; gap: 10px; width: 100%; min-width: 0; text-align: left; padding: 16px; border-radius: 12px }
|
|
39
46
|
.issue-card:hover, .issue-card[aria-current=true] { background: var(--paper) }
|