self-evolve-framework 1.6.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -23
- package/bin/cli.js +24 -67
- package/package.json +1 -1
- package/template/rules/knowledge/README.md +56 -0
- package/template/rules/knowledge/ant-design-vue.mdc +54 -0
- package/template/rules/knowledge/general.mdc +56 -0
- package/template/rules/knowledge/rust.mdc +55 -0
- package/template/rules/knowledge/shadcn-svelte.mdc +64 -0
- package/template/rules/knowledge/svelte.mdc +135 -0
- package/template/rules/knowledge/tailwind.mdc +66 -0
- package/template/rules/knowledge/tauri.mdc +65 -0
- package/template/rules/knowledge/typescript.mdc +41 -0
- package/template/rules/knowledge/vue.mdc +48 -0
- package/template/rules/ponytail.mdc +23 -98
- package/template/rules/self-evolve.mdc +24 -0
- package/template/skills/impeccable/SKILL.md +47 -174
- package/template/skills/skillopt-sleep/SKILL.md +32 -88
- package/template/skills/impeccable/agents/impeccable_asset_producer.toml +0 -92
- package/template/skills/impeccable/agents/impeccable_manual_edit_applier.toml +0 -95
- package/template/skills/impeccable/agents/openai.yaml +0 -4
- package/template/skills/impeccable/reference/adapt.md +0 -311
- package/template/skills/impeccable/reference/animate.md +0 -201
- package/template/skills/impeccable/reference/audit.md +0 -133
- package/template/skills/impeccable/reference/bolder.md +0 -113
- package/template/skills/impeccable/reference/brand.md +0 -108
- package/template/skills/impeccable/reference/clarify.md +0 -288
- package/template/skills/impeccable/reference/codex.md +0 -105
- package/template/skills/impeccable/reference/colorize.md +0 -257
- package/template/skills/impeccable/reference/craft.md +0 -123
- package/template/skills/impeccable/reference/critique.md +0 -790
- package/template/skills/impeccable/reference/delight.md +0 -302
- package/template/skills/impeccable/reference/distill.md +0 -111
- package/template/skills/impeccable/reference/document.md +0 -429
- package/template/skills/impeccable/reference/extract.md +0 -69
- package/template/skills/impeccable/reference/harden.md +0 -347
- package/template/skills/impeccable/reference/hooks.md +0 -90
- package/template/skills/impeccable/reference/init.md +0 -172
- package/template/skills/impeccable/reference/interaction-design.md +0 -189
- package/template/skills/impeccable/reference/layout.md +0 -161
- package/template/skills/impeccable/reference/live.md +0 -720
- package/template/skills/impeccable/reference/onboard.md +0 -234
- package/template/skills/impeccable/reference/optimize.md +0 -258
- package/template/skills/impeccable/reference/overdrive.md +0 -130
- package/template/skills/impeccable/reference/polish.md +0 -241
- package/template/skills/impeccable/reference/product.md +0 -60
- package/template/skills/impeccable/reference/quieter.md +0 -99
- package/template/skills/impeccable/reference/shape.md +0 -165
- package/template/skills/impeccable/reference/typeset.md +0 -279
- package/template/skills/impeccable/scripts/command-metadata.json +0 -94
- package/template/skills/impeccable/scripts/context-signals.mjs +0 -225
- package/template/skills/impeccable/scripts/context.mjs +0 -961
- package/template/skills/impeccable/scripts/critique-storage.mjs +0 -242
- package/template/skills/impeccable/scripts/detect-csp.mjs +0 -198
- package/template/skills/impeccable/scripts/detect.mjs +0 -21
- package/template/skills/impeccable/scripts/detector/browser/injected/index.mjs +0 -1937
- package/template/skills/impeccable/scripts/detector/cli/main.mjs +0 -290
- package/template/skills/impeccable/scripts/detector/design-system.mjs +0 -750
- package/template/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +0 -5138
- package/template/skills/impeccable/scripts/detector/detect-antipatterns.mjs +0 -50
- package/template/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +0 -277
- package/template/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +0 -568
- package/template/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +0 -1015
- package/template/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +0 -234
- package/template/skills/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +0 -189
- package/template/skills/impeccable/scripts/detector/findings.mjs +0 -12
- package/template/skills/impeccable/scripts/detector/node/file-system.mjs +0 -198
- package/template/skills/impeccable/scripts/detector/profile/profiler.mjs +0 -166
- package/template/skills/impeccable/scripts/detector/registry/antipatterns.mjs +0 -448
- package/template/skills/impeccable/scripts/detector/rules/checks.mjs +0 -2671
- package/template/skills/impeccable/scripts/detector/shared/color.mjs +0 -124
- package/template/skills/impeccable/scripts/detector/shared/constants.mjs +0 -101
- package/template/skills/impeccable/scripts/detector/shared/inline-ignores.mjs +0 -148
- package/template/skills/impeccable/scripts/detector/shared/page.mjs +0 -7
- package/template/skills/impeccable/scripts/hook-admin.mjs +0 -661
- package/template/skills/impeccable/scripts/hook-before-edit.mjs +0 -476
- package/template/skills/impeccable/scripts/hook-lib.mjs +0 -1632
- package/template/skills/impeccable/scripts/hook.mjs +0 -61
- package/template/skills/impeccable/scripts/lib/design-parser.mjs +0 -842
- package/template/skills/impeccable/scripts/lib/impeccable-config.mjs +0 -638
- package/template/skills/impeccable/scripts/lib/impeccable-paths.mjs +0 -128
- package/template/skills/impeccable/scripts/lib/is-generated.mjs +0 -69
- package/template/skills/impeccable/scripts/lib/target-args.mjs +0 -42
- package/template/skills/impeccable/scripts/live/browser-script-parts.mjs +0 -49
- package/template/skills/impeccable/scripts/live/completion.mjs +0 -19
- package/template/skills/impeccable/scripts/live/event-validation.mjs +0 -137
- package/template/skills/impeccable/scripts/live/insert-ui.mjs +0 -458
- package/template/skills/impeccable/scripts/live/manual-apply.mjs +0 -939
- package/template/skills/impeccable/scripts/live/manual-edit-routes.mjs +0 -357
- package/template/skills/impeccable/scripts/live/manual-edits-buffer.mjs +0 -152
- package/template/skills/impeccable/scripts/live/session-store.mjs +0 -289
- package/template/skills/impeccable/scripts/live/svelte-component.mjs +0 -826
- package/template/skills/impeccable/scripts/live/sveltekit-adapter.mjs +0 -274
- package/template/skills/impeccable/scripts/live/ui-core.mjs +0 -180
- package/template/skills/impeccable/scripts/live/vocabulary.mjs +0 -36
- package/template/skills/impeccable/scripts/live-accept.mjs +0 -812
- package/template/skills/impeccable/scripts/live-browser-dom.js +0 -146
- package/template/skills/impeccable/scripts/live-browser-session.js +0 -123
- package/template/skills/impeccable/scripts/live-browser.js +0 -11173
- package/template/skills/impeccable/scripts/live-commit-manual-edits.mjs +0 -1241
- package/template/skills/impeccable/scripts/live-complete.mjs +0 -75
- package/template/skills/impeccable/scripts/live-copy-edit-agent.mjs +0 -683
- package/template/skills/impeccable/scripts/live-discard-manual-edits.mjs +0 -51
- package/template/skills/impeccable/scripts/live-inject.mjs +0 -583
- package/template/skills/impeccable/scripts/live-insert.mjs +0 -272
- package/template/skills/impeccable/scripts/live-manual-edit-evidence.mjs +0 -363
- package/template/skills/impeccable/scripts/live-poll.mjs +0 -384
- package/template/skills/impeccable/scripts/live-resume.mjs +0 -94
- package/template/skills/impeccable/scripts/live-server.mjs +0 -1135
- package/template/skills/impeccable/scripts/live-status.mjs +0 -61
- package/template/skills/impeccable/scripts/live-target.mjs +0 -30
- package/template/skills/impeccable/scripts/live-wrap.mjs +0 -894
- package/template/skills/impeccable/scripts/live.mjs +0 -297
- package/template/skills/impeccable/scripts/modern-screenshot.umd.js +0 -14
- package/template/skills/impeccable/scripts/palette.mjs +0 -633
- package/template/skills/impeccable/scripts/pin.mjs +0 -214
- package/template/skills/skillopt-sleep/configs/_base_/default.yaml +0 -103
- package/template/skills/skillopt-sleep/configs/alfworld/default.yaml +0 -29
- package/template/skills/skillopt-sleep/configs/docvqa/default.yaml +0 -28
- package/template/skills/skillopt-sleep/configs/features/soft_gate.yaml +0 -47
- package/template/skills/skillopt-sleep/configs/livemathematicianbench/default.yaml +0 -22
- package/template/skills/skillopt-sleep/configs/officeqa/default.yaml +0 -34
- package/template/skills/skillopt-sleep/configs/searchqa/default.yaml +0 -32
- package/template/skills/skillopt-sleep/configs/spreadsheetbench/default.yaml +0 -34
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/__init__.py +0 -28
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/config.py +0 -282
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/datasets/__init__.py +0 -7
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/datasets/base.py +0 -512
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/engine/__init__.py +0 -9
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/engine/trainer.py +0 -2379
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/__init__.py +0 -1
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/README.md +0 -43
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/config_template.yaml +0 -55
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/env_template.py +0 -151
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/loader_template.py +0 -87
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/__init__.py +0 -5
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/adapter.py +0 -428
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/dataloader.py +0 -123
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/analyst_error.md +0 -55
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/analyst_success.md +0 -33
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_no_history.md +0 -8
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_with_history.md +0 -9
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_with_memory.md +0 -16
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/reflect.py +0 -4
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/rollout.py +0 -366
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/skills/initial.md +0 -45
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/__init__.py +0 -9
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_envs.py +0 -221
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_projection.py +0 -60
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_prompts.py +0 -8
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/config_tw.yaml +0 -145
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/env_base.py +0 -84
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/env_manager.py +0 -139
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/memory.py +0 -87
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/base.py +0 -329
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/__init__.py +0 -1
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/adapter.py +0 -90
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/dataloader.py +0 -61
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/evaluator.py +0 -113
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/analyst_error.md +0 -35
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/analyst_success.md +0 -24
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/rollout_system.md +0 -12
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/rollout.py +0 -391
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/skills/initial.md +0 -11
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/__init__.py +0 -1
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/adapter.py +0 -129
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/dataloader.py +0 -308
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/evaluator.py +0 -62
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/analyst_error.md +0 -37
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/analyst_success.md +0 -25
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/rollout_system.md +0 -12
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/reflect.py +0 -4
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/rollout.py +0 -434
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/skills/initial.md +0 -16
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/__init__.py +0 -1
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/adapter.py +0 -112
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/dataloader.py +0 -71
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/evaluator.py +0 -46
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/analyst_error.md +0 -37
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/analyst_success.md +0 -25
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/rollout_system.md +0 -15
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/rollout.py +0 -799
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/skills/initial.md +0 -15
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/tool_runtime.py +0 -552
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/__init__.py +0 -1
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/adapter.py +0 -96
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/dataloader.py +0 -42
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/evaluator.py +0 -100
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/analyst_error.md +0 -46
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/analyst_success.md +0 -32
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/rollout_system.md +0 -13
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/reflect.py +0 -4
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/rollout.py +0 -494
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/skills/initial.md +0 -3
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/__init__.py +0 -5
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/adapter.py +0 -159
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/codegen_agent.py +0 -731
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/dataloader.py +0 -37
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/evaluator.py +0 -158
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/executor.py +0 -67
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/analyst_error.md +0 -46
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/analyst_success.md +0 -32
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/codegen_system.md +0 -1
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/critical_rules.md +0 -9
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/react_system.md +0 -21
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/react_agent.py +0 -395
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/reflect.py +0 -4
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/rollout.py +0 -979
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/skills/initial.md +0 -56
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/evaluation/__init__.py +0 -13
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/evaluation/gate.py +0 -148
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/__init__.py +0 -15
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/aggregate.py +0 -253
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/reflect.py +0 -635
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/__init__.py +0 -514
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/azure_openai.py +0 -915
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/backend_config.py +0 -185
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/claude_backend.py +0 -371
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/codex_backend.py +0 -666
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/codex_harness.py +0 -1057
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/common.py +0 -229
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/minimax_backend.py +0 -277
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/qwen_backend.py +0 -456
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/router.py +0 -236
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/__init__.py +0 -15
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/appendix.py +0 -156
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/clip.py +0 -109
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/lr_autonomous.py +0 -108
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/meta_skill.py +0 -79
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/rewrite.py +0 -59
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/scheduler.py +0 -127
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/select.py +0 -4
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/skill.py +0 -201
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/skill_aware.py +0 -206
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/slow_update.py +0 -396
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/update_modes.py +0 -135
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/__init__.py +0 -63
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error.md +0 -41
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error_full_rewrite.md +0 -32
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error_rewrite.md +0 -44
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success.md +0 -36
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success_full_rewrite.md +0 -30
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success_rewrite.md +0 -33
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/lr_autonomous.md +0 -20
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure.md +0 -30
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure_full_rewrite.md +0 -28
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure_rewrite.md +0 -26
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final.md +0 -33
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final_full_rewrite.md +0 -28
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final_rewrite.md +0 -25
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success.md +0 -28
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success_full_rewrite.md +0 -28
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success_rewrite.md +0 -25
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/meta_skill.md +0 -40
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/ranking.md +0 -20
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/ranking_rewrite.md +0 -15
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/rewrite_skill.md +0 -25
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/slow_update.md +0 -60
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/scheduler/__init__.py +0 -8
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/types.py +0 -306
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/__init__.py +0 -4
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/json_utils.py +0 -172
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/scoring.py +0 -28
- package/template/skills/skillopt-sleep/scripts/python/__init__.py +0 -20
- package/template/skills/skillopt-sleep/scripts/python/__main__.py +0 -343
- package/template/skills/skillopt-sleep/scripts/python/backend.py +0 -1371
- package/template/skills/skillopt-sleep/scripts/python/budget.py +0 -75
- package/template/skills/skillopt-sleep/scripts/python/config.py +0 -162
- package/template/skills/skillopt-sleep/scripts/python/consolidate.py +0 -238
- package/template/skills/skillopt-sleep/scripts/python/cycle.py +0 -291
- package/template/skills/skillopt-sleep/scripts/python/dream.py +0 -138
- package/template/skills/skillopt-sleep/scripts/python/experiments/__init__.py +0 -1
- package/template/skills/skillopt-sleep/scripts/python/experiments/gbrain_bench.py +0 -119
- package/template/skills/skillopt-sleep/scripts/python/experiments/personas.py +0 -86
- package/template/skills/skillopt-sleep/scripts/python/experiments/report.py +0 -132
- package/template/skills/skillopt-sleep/scripts/python/experiments/run_experiment.py +0 -178
- package/template/skills/skillopt-sleep/scripts/python/experiments/run_gbrain.py +0 -209
- package/template/skills/skillopt-sleep/scripts/python/experiments/run_transfer.py +0 -155
- package/template/skills/skillopt-sleep/scripts/python/experiments/sweep.py +0 -164
- package/template/skills/skillopt-sleep/scripts/python/gate.py +0 -50
- package/template/skills/skillopt-sleep/scripts/python/harvest.py +0 -304
- package/template/skills/skillopt-sleep/scripts/python/harvest_codex.py +0 -253
- package/template/skills/skillopt-sleep/scripts/python/harvest_sources.py +0 -41
- package/template/skills/skillopt-sleep/scripts/python/judges.py +0 -84
- package/template/skills/skillopt-sleep/scripts/python/llm_miner.py +0 -134
- package/template/skills/skillopt-sleep/scripts/python/memory.py +0 -129
- package/template/skills/skillopt-sleep/scripts/python/mine.py +0 -312
- package/template/skills/skillopt-sleep/scripts/python/replay.py +0 -146
- package/template/skills/skillopt-sleep/scripts/python/rollout.py +0 -153
- package/template/skills/skillopt-sleep/scripts/python/scheduler.py +0 -138
- package/template/skills/skillopt-sleep/scripts/python/slow_update.py +0 -142
- package/template/skills/skillopt-sleep/scripts/python/staging.py +0 -103
- package/template/skills/skillopt-sleep/scripts/python/state.py +0 -96
- package/template/skills/skillopt-sleep/scripts/python/tasks_file.py +0 -81
- package/template/skills/skillopt-sleep/scripts/python/types.py +0 -146
- package/template/skills/skillopt-sleep/scripts/shell/__init__.py +0 -0
- package/template/skills/skillopt-sleep/scripts/shell/eval_only.py +0 -466
- package/template/skills/skillopt-sleep/scripts/shell/materialize_searchqa.py +0 -148
- package/template/skills/skillopt-sleep/scripts/shell/run_alfworld.sh +0 -60
- package/template/skills/skillopt-sleep/scripts/shell/run_searchqa.sh +0 -40
- package/template/skills/skillopt-sleep/scripts/shell/run_spreadsheetbench.sh +0 -39
- package/template/skills/skillopt-sleep/scripts/shell/train.py +0 -556
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
"""SkillOpt-Sleep — benchmark sweep driver.
|
|
2
|
-
|
|
3
|
-
Runs many (backend, model, seed, transfer-pair) configurations SEQUENTIALLY in
|
|
4
|
-
one process, appending each result to a JSONL file as it finishes. Designed to
|
|
5
|
-
run unattended in the background; safe to interrupt (already-written rows
|
|
6
|
-
survive) and resume (skip configs whose row already exists).
|
|
7
|
-
|
|
8
|
-
Then `report.py` turns the JSONL into a presented Markdown scorecard.
|
|
9
|
-
|
|
10
|
-
Usage:
|
|
11
|
-
python -m skillopt_sleep.experiments.sweep --plan quick --out docs/sleep/sweep.jsonl
|
|
12
|
-
python -m skillopt_sleep.experiments.sweep --plan full --out docs/sleep/sweep.jsonl
|
|
13
|
-
"""
|
|
14
|
-
from __future__ import annotations
|
|
15
|
-
|
|
16
|
-
import argparse
|
|
17
|
-
import json
|
|
18
|
-
import os
|
|
19
|
-
import sys
|
|
20
|
-
import time
|
|
21
|
-
from typing import Any, Dict, List
|
|
22
|
-
|
|
23
|
-
from skillopt_sleep.backend import build_backend, get_backend
|
|
24
|
-
from skillopt_sleep.experiments.gbrain_bench import find_data_root, load_seed
|
|
25
|
-
from skillopt_sleep.experiments.run_gbrain import run_seed as bench_seed
|
|
26
|
-
from skillopt_sleep.experiments.run_transfer import run_seed as transfer_seed
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# Plans: lists of config dicts. Kept small per-run to bound cost/latency.
|
|
30
|
-
def _direct_cfg(backend, model, seed, nights=2):
|
|
31
|
-
return {"kind": "direct", "backend": backend, "model": model, "seed": seed, "nights": nights}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _dual_cfg(opt_backend, opt_model, tgt_backend, tgt_model, seed, nights=2):
|
|
35
|
-
# a 'direct' run on a DualBackend: strong optimizer proposes, weak target runs
|
|
36
|
-
return {"kind": "dual", "optimizer_backend": opt_backend, "optimizer_model": opt_model,
|
|
37
|
-
"target_backend": tgt_backend, "target_model": tgt_model, "seed": seed, "nights": nights}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def _transfer_cfg(sb, sm, tb, tm, seed, nights=2):
|
|
41
|
-
return {"kind": "transfer", "source_backend": sb, "source_model": sm,
|
|
42
|
-
"target_backend": tb, "target_model": tm, "seed": seed, "nights": nights}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
PLANS: Dict[str, List[Dict[str, Any]]] = {
|
|
46
|
-
# one cheap seed each, both backends — fast sanity
|
|
47
|
-
"quick": [
|
|
48
|
-
_direct_cfg("claude", "haiku", "brief-writer", 1),
|
|
49
|
-
_direct_cfg("codex", "", "brief-writer", 2),
|
|
50
|
-
],
|
|
51
|
-
# SkillOpt-faithful: STRONG optimizer (sonnet) proposes, WEAK target (haiku)
|
|
52
|
-
# runs — the reliable config. Plus Codex self-optimized. All 4 gbrain seeds,
|
|
53
|
-
# including quick-answerer (real tool loop).
|
|
54
|
-
"direct": [
|
|
55
|
-
_dual_cfg("claude", "sonnet", "claude", "haiku", "brief-writer"),
|
|
56
|
-
_dual_cfg("claude", "sonnet", "claude", "haiku", "advisor"),
|
|
57
|
-
_dual_cfg("claude", "sonnet", "claude", "haiku", "thorough-analyst"),
|
|
58
|
-
_dual_cfg("claude", "sonnet", "claude", "haiku", "quick-answerer"),
|
|
59
|
-
_direct_cfg("codex", "", "brief-writer"),
|
|
60
|
-
_direct_cfg("codex", "", "advisor"),
|
|
61
|
-
_direct_cfg("codex", "", "quick-answerer"),
|
|
62
|
-
],
|
|
63
|
-
# the price-difference story: optimize cheap, deploy expensive (and reverse)
|
|
64
|
-
"transfer": [
|
|
65
|
-
_transfer_cfg("claude", "haiku", "claude", "sonnet", "brief-writer"),
|
|
66
|
-
_transfer_cfg("claude", "sonnet", "claude", "haiku", "brief-writer"),
|
|
67
|
-
_transfer_cfg("codex", "", "claude", "haiku", "brief-writer"),
|
|
68
|
-
_transfer_cfg("claude", "haiku", "codex", "", "brief-writer"),
|
|
69
|
-
],
|
|
70
|
-
}
|
|
71
|
-
PLANS["full"] = PLANS["direct"] + PLANS["transfer"]
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def _cfg_key(c: Dict[str, Any]) -> str:
|
|
75
|
-
return json.dumps({k: c[k] for k in sorted(c)}, ensure_ascii=False)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def _load_done(out_path: str) -> set:
|
|
79
|
-
done = set()
|
|
80
|
-
if os.path.exists(out_path):
|
|
81
|
-
with open(out_path) as f:
|
|
82
|
-
for line in f:
|
|
83
|
-
try:
|
|
84
|
-
row = json.loads(line)
|
|
85
|
-
if "cfg_key" in row:
|
|
86
|
-
done.add(row["cfg_key"])
|
|
87
|
-
except Exception:
|
|
88
|
-
pass
|
|
89
|
-
return done
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def _append(out_path: str, row: Dict[str, Any]) -> None:
|
|
93
|
-
os.makedirs(os.path.dirname(out_path) or ".", exist_ok=True)
|
|
94
|
-
with open(out_path, "a") as f:
|
|
95
|
-
f.write(json.dumps(row, ensure_ascii=False) + "\n")
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def run_one(cfg: Dict[str, Any], data_root: str, codex_path: str,
|
|
99
|
-
limit_replay: int, limit_holdout: int) -> Dict[str, Any]:
|
|
100
|
-
seed = cfg["seed"]
|
|
101
|
-
skill, tasks = load_seed(data_root, seed)
|
|
102
|
-
t0 = time.time()
|
|
103
|
-
if cfg["kind"] in ("direct", "dual"):
|
|
104
|
-
if cfg["kind"] == "dual":
|
|
105
|
-
be = build_backend(
|
|
106
|
-
optimizer_backend=cfg["optimizer_backend"], optimizer_model=cfg.get("optimizer_model", ""),
|
|
107
|
-
target_backend=cfg["target_backend"], target_model=cfg.get("target_model", ""),
|
|
108
|
-
codex_path=codex_path,
|
|
109
|
-
)
|
|
110
|
-
else:
|
|
111
|
-
be = get_backend(cfg["backend"], model=cfg.get("model", ""), codex_path=codex_path)
|
|
112
|
-
r = bench_seed(be, seed, skill, tasks, nights=cfg["nights"],
|
|
113
|
-
limit_replay=limit_replay, limit_holdout=limit_holdout)
|
|
114
|
-
out = {"baseline": r["held_out_before"], "after": r["held_out_after"],
|
|
115
|
-
"improved": r["improved"], "tokens": be.tokens_used()}
|
|
116
|
-
else:
|
|
117
|
-
src = get_backend(cfg["source_backend"], model=cfg.get("source_model", ""), codex_path=codex_path)
|
|
118
|
-
tgt = get_backend(cfg["target_backend"], model=cfg.get("target_model", ""), codex_path=codex_path)
|
|
119
|
-
r = transfer_seed(seed, skill, tasks, source=src, target=tgt, nights=cfg["nights"],
|
|
120
|
-
edit_budget=4, limit_replay=limit_replay, limit_holdout=limit_holdout,
|
|
121
|
-
do_direct=False)
|
|
122
|
-
out = {"baseline_target": r["baseline_target"], "transferred": r["transferred"],
|
|
123
|
-
"transfer_gain": r["transfer_gain"],
|
|
124
|
-
"tokens": src.tokens_used() + tgt.tokens_used()}
|
|
125
|
-
out.update({"cfg": cfg, "cfg_key": _cfg_key(cfg), "elapsed_s": round(time.time() - t0, 1)})
|
|
126
|
-
return out
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def main(argv=None) -> int:
|
|
130
|
-
ap = argparse.ArgumentParser(description="SkillOpt-Sleep benchmark sweep")
|
|
131
|
-
ap.add_argument("--plan", default="quick", choices=list(PLANS.keys()))
|
|
132
|
-
ap.add_argument("--out", default="docs/sleep/sweep.jsonl")
|
|
133
|
-
ap.add_argument("--data-root", default="")
|
|
134
|
-
ap.add_argument("--codex-path", default="")
|
|
135
|
-
ap.add_argument("--limit-replay", type=int, default=3)
|
|
136
|
-
ap.add_argument("--limit-holdout", type=int, default=3)
|
|
137
|
-
args = ap.parse_args(argv)
|
|
138
|
-
|
|
139
|
-
data_root = find_data_root(args.data_root)
|
|
140
|
-
if not data_root:
|
|
141
|
-
print("ERROR: gbrain-evals data not found; pass --data-root", file=sys.stderr)
|
|
142
|
-
return 2
|
|
143
|
-
|
|
144
|
-
plan = PLANS[args.plan]
|
|
145
|
-
done = _load_done(args.out)
|
|
146
|
-
print(f"[sweep] plan={args.plan} configs={len(plan)} already_done={len(done)} -> {args.out}")
|
|
147
|
-
for i, cfg in enumerate(plan, 1):
|
|
148
|
-
key = _cfg_key(cfg)
|
|
149
|
-
if key in done:
|
|
150
|
-
print(f"[sweep] ({i}/{len(plan)}) skip (done): {cfg}")
|
|
151
|
-
continue
|
|
152
|
-
print(f"[sweep] ({i}/{len(plan)}) running: {cfg}", flush=True)
|
|
153
|
-
try:
|
|
154
|
-
row = run_one(cfg, data_root, args.codex_path, args.limit_replay, args.limit_holdout)
|
|
155
|
-
except Exception as e: # never let one config kill the sweep
|
|
156
|
-
row = {"cfg": cfg, "cfg_key": key, "error": f"{type(e).__name__}: {e}"}
|
|
157
|
-
_append(args.out, row)
|
|
158
|
-
print(f"[sweep] -> {json.dumps({k: v for k, v in row.items() if k not in ('cfg','cfg_key')})}", flush=True)
|
|
159
|
-
print(f"[sweep] done. rows in {args.out}: {len(_load_done(args.out))}")
|
|
160
|
-
return 0
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if __name__ == "__main__":
|
|
164
|
-
sys.exit(main())
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"""SkillOpt-Sleep — vendored validation gate.
|
|
2
|
-
|
|
3
|
-
This is a self-contained copy of the SkillOpt validation gate so the sleep
|
|
4
|
-
engine has ZERO dependency on the research package (skillopt/*). The research
|
|
5
|
-
repo's ``skillopt.evaluation.gate`` is the reference implementation and the two
|
|
6
|
-
are kept behaviourally identical; vendoring keeps this open-source tool
|
|
7
|
-
decoupled from the paper's experiment code.
|
|
8
|
-
"""
|
|
9
|
-
from __future__ import annotations
|
|
10
|
-
|
|
11
|
-
from dataclasses import dataclass
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass(frozen=True)
|
|
15
|
-
class GateResult:
|
|
16
|
-
action: str # "accept_new_best" | "accept" | "reject"
|
|
17
|
-
current_skill: str
|
|
18
|
-
current_score: float
|
|
19
|
-
best_skill: str
|
|
20
|
-
best_score: float
|
|
21
|
-
best_step: int
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def select_gate_score(hard: float, soft: float, metric: str = "hard",
|
|
25
|
-
mixed_weight: float = 0.5) -> float:
|
|
26
|
-
"""Project (hard, soft) onto a single comparison metric."""
|
|
27
|
-
if metric == "hard":
|
|
28
|
-
return float(hard)
|
|
29
|
-
if metric == "soft":
|
|
30
|
-
return float(soft)
|
|
31
|
-
if metric == "mixed":
|
|
32
|
-
w = max(0.0, min(1.0, float(mixed_weight)))
|
|
33
|
-
return (1.0 - w) * float(hard) + w * float(soft)
|
|
34
|
-
raise ValueError(f"unknown gate metric {metric!r}; expected hard/soft/mixed")
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def evaluate_gate(candidate_skill: str, cand_hard: float, current_skill: str,
|
|
38
|
-
current_score: float, best_skill: str, best_score: float,
|
|
39
|
-
best_step: int, global_step: int, *, cand_soft: float = 0.0,
|
|
40
|
-
metric: str = "hard", mixed_weight: float = 0.5) -> GateResult:
|
|
41
|
-
"""Pure gate decision: compare candidate score to current/best."""
|
|
42
|
-
cand_score = select_gate_score(cand_hard, cand_soft, metric, mixed_weight)
|
|
43
|
-
if cand_score > current_score:
|
|
44
|
-
if cand_score > best_score:
|
|
45
|
-
return GateResult("accept_new_best", candidate_skill, cand_score,
|
|
46
|
-
candidate_skill, cand_score, global_step)
|
|
47
|
-
return GateResult("accept", candidate_skill, cand_score,
|
|
48
|
-
best_skill, best_score, best_step)
|
|
49
|
-
return GateResult("reject", current_skill, current_score,
|
|
50
|
-
best_skill, best_score, best_step)
|
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
"""SkillOpt-Sleep — Stage 1: harvest.
|
|
2
|
-
|
|
3
|
-
Read the user's local Claude Code records (read-only) and normalize them
|
|
4
|
-
into :class:`SessionDigest` objects.
|
|
5
|
-
|
|
6
|
-
Sources (verified schema):
|
|
7
|
-
* ~/.claude/history.jsonl — one JSON/line:
|
|
8
|
-
{"display": <prompt text>, "pastedContents": {...},
|
|
9
|
-
"timestamp": <epoch ms>, "project": <abs path>}
|
|
10
|
-
* ~/.claude/projects/<slug>/<sessionId>.jsonl — one record/line; the
|
|
11
|
-
records we care about have type "user"/"assistant" and carry:
|
|
12
|
-
message{role, content}, cwd, gitBranch, timestamp, sessionId, version
|
|
13
|
-
|
|
14
|
-
This module performs NO writes and NO network calls.
|
|
15
|
-
"""
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
import json
|
|
19
|
-
import os
|
|
20
|
-
from datetime import datetime
|
|
21
|
-
from typing import Any, Dict, Iterable, List, Optional
|
|
22
|
-
|
|
23
|
-
from skillopt_sleep.types import SessionDigest
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# Heuristic phrases that signal the user (dis)approving of prior output.
|
|
27
|
-
# English-only by default. Users whose sessions are in another language can add
|
|
28
|
-
# their own phrases via the SKILLOPT_SLEEP_NEG_FEEDBACK / _POS_FEEDBACK env vars
|
|
29
|
-
# (comma-separated), so the capability is extensible without hardcoding locales.
|
|
30
|
-
_NEGATIVE_FEEDBACK = (
|
|
31
|
-
"still broken", "still not", "still wrong", "doesn't work", "does not work",
|
|
32
|
-
"not working", "that's wrong", "thats wrong", "incorrect", "wrong",
|
|
33
|
-
"no,", "nope", "fix it", "didn't", "did not", "broken", "error again",
|
|
34
|
-
"still failing", "still fails", "not fixed", "revert", "undo",
|
|
35
|
-
)
|
|
36
|
-
_POSITIVE_FEEDBACK = (
|
|
37
|
-
"thanks", "thank you", "perfect", "great", "works now", "fixed",
|
|
38
|
-
"that works", "lgtm", "looks good", "nice", "awesome", "correct",
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _extra_phrases(env_var: str) -> tuple:
|
|
43
|
-
raw = os.environ.get(env_var, "")
|
|
44
|
-
return tuple(p.strip().lower() for p in raw.split(",") if p.strip())
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
_NEGATIVE_FEEDBACK = _NEGATIVE_FEEDBACK + _extra_phrases("SKILLOPT_SLEEP_NEG_FEEDBACK")
|
|
48
|
-
_POSITIVE_FEEDBACK = _POSITIVE_FEEDBACK + _extra_phrases("SKILLOPT_SLEEP_POS_FEEDBACK")
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def _iter_jsonl(path: str) -> Iterable[Dict[str, Any]]:
|
|
52
|
-
try:
|
|
53
|
-
with open(path, encoding="utf-8") as f:
|
|
54
|
-
for line in f:
|
|
55
|
-
line = line.strip()
|
|
56
|
-
if not line:
|
|
57
|
-
continue
|
|
58
|
-
try:
|
|
59
|
-
yield json.loads(line)
|
|
60
|
-
except Exception:
|
|
61
|
-
continue
|
|
62
|
-
except (FileNotFoundError, IsADirectoryError, PermissionError):
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def _text_from_content(content: Any) -> str:
|
|
67
|
-
"""Flatten a message.content (str or list of blocks) into text."""
|
|
68
|
-
if isinstance(content, str):
|
|
69
|
-
return content
|
|
70
|
-
if isinstance(content, list):
|
|
71
|
-
parts: List[str] = []
|
|
72
|
-
for b in content:
|
|
73
|
-
if isinstance(b, dict):
|
|
74
|
-
if b.get("type") == "text" and b.get("text"):
|
|
75
|
-
parts.append(str(b["text"]))
|
|
76
|
-
return "\n".join(parts)
|
|
77
|
-
return ""
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def _tool_names_from_content(content: Any) -> List[str]:
|
|
81
|
-
names: List[str] = []
|
|
82
|
-
if isinstance(content, list):
|
|
83
|
-
for b in content:
|
|
84
|
-
if isinstance(b, dict) and b.get("type") == "tool_use" and b.get("name"):
|
|
85
|
-
names.append(str(b["name"]))
|
|
86
|
-
return names
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def _detect_feedback(text: str) -> List[str]:
|
|
90
|
-
low = text.lower()
|
|
91
|
-
sig: List[str] = []
|
|
92
|
-
for ph in _NEGATIVE_FEEDBACK:
|
|
93
|
-
if ph in low:
|
|
94
|
-
sig.append("neg:" + ph)
|
|
95
|
-
for ph in _POSITIVE_FEEDBACK:
|
|
96
|
-
if ph in low:
|
|
97
|
-
sig.append("pos:" + ph)
|
|
98
|
-
return sig
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def _is_meta_prompt(text: str) -> bool:
|
|
102
|
-
"""Skip slash-commands / system noise that aren't real user intents."""
|
|
103
|
-
t = text.strip()
|
|
104
|
-
if not t:
|
|
105
|
-
return True
|
|
106
|
-
if t.startswith("<") and t.endswith(">"):
|
|
107
|
-
return True
|
|
108
|
-
if t.startswith("/") and len(t.split()) <= 3:
|
|
109
|
-
return True
|
|
110
|
-
if t.startswith("[Pasted text") or t.startswith("Caveat:"):
|
|
111
|
-
return True
|
|
112
|
-
return False
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
# ── Issue #62: filter headless replay sessions ─────────────────────────
|
|
116
|
-
|
|
117
|
-
# Prompt markers generated by the engine's own headless `claude -p` calls
|
|
118
|
-
# (judge, reflect, attempt). If the sole user prompt in a single-turn
|
|
119
|
-
# session matches any of these, the session is engine-generated, not a
|
|
120
|
-
# real user task.
|
|
121
|
-
_REPLAY_PROMPT_MARKERS = (
|
|
122
|
-
"## CURRENT SKILL",
|
|
123
|
-
"## FAILED TASKS",
|
|
124
|
-
"## SUCCESSFUL TASKS",
|
|
125
|
-
"## OUTPUT FORMAT",
|
|
126
|
-
"You are a strict grader",
|
|
127
|
-
"Score the response 0.0-1.0",
|
|
128
|
-
"You are SkillOpt-Sleep",
|
|
129
|
-
"## TASK\n",
|
|
130
|
-
"## SKILL\n",
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def _is_headless_replay(digest: "SessionDigest") -> bool:
|
|
135
|
-
"""Detect sessions created by the engine's own headless replay calls.
|
|
136
|
-
|
|
137
|
-
Heuristics (conservatively applied):
|
|
138
|
-
1. Session has exactly 1 user turn AND
|
|
139
|
-
2. The sole prompt matches engine-generated patterns (grader/reflect),
|
|
140
|
-
OR the session lasted < 3 seconds (programmatic, not interactive).
|
|
141
|
-
Multi-turn sessions are always kept (interactive by definition).
|
|
142
|
-
"""
|
|
143
|
-
if digest.n_user_turns > 1:
|
|
144
|
-
return False
|
|
145
|
-
if digest.n_user_turns == 0:
|
|
146
|
-
return True
|
|
147
|
-
prompt = digest.user_prompts[0] if digest.user_prompts else ""
|
|
148
|
-
for marker in _REPLAY_PROMPT_MARKERS:
|
|
149
|
-
if marker in prompt:
|
|
150
|
-
return True
|
|
151
|
-
# Sub-3-second single-turn sessions with short prompts are almost
|
|
152
|
-
# certainly programmatic (engine grader/judge calls). We require the
|
|
153
|
-
# prompt to also be short (<200 chars) to avoid false-positives on
|
|
154
|
-
# real one-shot questions that Claude happens to answer quickly.
|
|
155
|
-
if digest.started_at and digest.ended_at and len(prompt) < 200:
|
|
156
|
-
try:
|
|
157
|
-
fmt = "%Y-%m-%dT%H:%M:%S"
|
|
158
|
-
start = datetime.strptime(digest.started_at[:19], fmt)
|
|
159
|
-
end = datetime.strptime(digest.ended_at[:19], fmt)
|
|
160
|
-
if (end - start).total_seconds() < 3:
|
|
161
|
-
return True
|
|
162
|
-
except (ValueError, TypeError):
|
|
163
|
-
pass
|
|
164
|
-
return False
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def digest_transcript(path: str) -> Optional[SessionDigest]:
|
|
168
|
-
"""Build a SessionDigest from one ``<sessionId>.jsonl`` transcript."""
|
|
169
|
-
session_id = os.path.splitext(os.path.basename(path))[0]
|
|
170
|
-
project = ""
|
|
171
|
-
git_branch = ""
|
|
172
|
-
started = ""
|
|
173
|
-
ended = ""
|
|
174
|
-
user_prompts: List[str] = []
|
|
175
|
-
assistant_finals: List[str] = []
|
|
176
|
-
tools: List[str] = []
|
|
177
|
-
files: List[str] = []
|
|
178
|
-
feedback: List[str] = []
|
|
179
|
-
n_user = 0
|
|
180
|
-
n_asst = 0
|
|
181
|
-
|
|
182
|
-
for rec in _iter_jsonl(path):
|
|
183
|
-
rtype = rec.get("type")
|
|
184
|
-
ts = rec.get("timestamp")
|
|
185
|
-
if isinstance(ts, str) and ts:
|
|
186
|
-
if not started:
|
|
187
|
-
started = ts
|
|
188
|
-
ended = ts
|
|
189
|
-
if rec.get("cwd") and not project:
|
|
190
|
-
project = str(rec.get("cwd"))
|
|
191
|
-
if rec.get("gitBranch") and not git_branch:
|
|
192
|
-
git_branch = str(rec.get("gitBranch"))
|
|
193
|
-
if rtype == "file-history-snapshot":
|
|
194
|
-
snap = rec.get("snapshot") or rec.get("files") or {}
|
|
195
|
-
if isinstance(snap, dict):
|
|
196
|
-
files.extend([str(k) for k in list(snap.keys())[:20]])
|
|
197
|
-
msg = rec.get("message")
|
|
198
|
-
if not isinstance(msg, dict):
|
|
199
|
-
continue
|
|
200
|
-
role = msg.get("role")
|
|
201
|
-
content = msg.get("content")
|
|
202
|
-
if role == "user":
|
|
203
|
-
text = _text_from_content(content)
|
|
204
|
-
if text and not _is_meta_prompt(text):
|
|
205
|
-
n_user += 1
|
|
206
|
-
user_prompts.append(text.strip())
|
|
207
|
-
feedback.extend(_detect_feedback(text))
|
|
208
|
-
elif role == "assistant":
|
|
209
|
-
n_asst += 1
|
|
210
|
-
tools.extend(_tool_names_from_content(content))
|
|
211
|
-
text = _text_from_content(content)
|
|
212
|
-
if text.strip():
|
|
213
|
-
assistant_finals.append(text.strip())
|
|
214
|
-
|
|
215
|
-
if n_user == 0 and n_asst == 0:
|
|
216
|
-
return None
|
|
217
|
-
|
|
218
|
-
# de-dup tools/files preserving order
|
|
219
|
-
def _dedup(xs: List[str]) -> List[str]:
|
|
220
|
-
seen = set()
|
|
221
|
-
out = []
|
|
222
|
-
for x in xs:
|
|
223
|
-
if x not in seen:
|
|
224
|
-
seen.add(x)
|
|
225
|
-
out.append(x)
|
|
226
|
-
return out
|
|
227
|
-
|
|
228
|
-
return SessionDigest(
|
|
229
|
-
session_id=session_id,
|
|
230
|
-
project=project,
|
|
231
|
-
git_branch=git_branch,
|
|
232
|
-
started_at=started,
|
|
233
|
-
ended_at=ended,
|
|
234
|
-
user_prompts=user_prompts,
|
|
235
|
-
assistant_finals=assistant_finals[-5:], # last few finals are the useful ones
|
|
236
|
-
tools_used=_dedup(tools),
|
|
237
|
-
files_touched=_dedup(files),
|
|
238
|
-
feedback_signals=feedback,
|
|
239
|
-
n_user_turns=n_user,
|
|
240
|
-
n_assistant_turns=n_asst,
|
|
241
|
-
raw_path=path,
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
def _project_matches(project: str, scope: Any, invoked: str) -> bool:
|
|
246
|
-
if scope == "all":
|
|
247
|
-
return True
|
|
248
|
-
if isinstance(scope, (list, tuple)):
|
|
249
|
-
return any(os.path.abspath(project) == os.path.abspath(p) for p in scope)
|
|
250
|
-
# "invoked": match the invoked project (or a subdir of it)
|
|
251
|
-
if not invoked:
|
|
252
|
-
return True
|
|
253
|
-
a = os.path.abspath(project)
|
|
254
|
-
b = os.path.abspath(invoked)
|
|
255
|
-
return a == b or a.startswith(b + os.sep) or b.startswith(a + os.sep)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def harvest(
|
|
259
|
-
transcripts_dir: str,
|
|
260
|
-
*,
|
|
261
|
-
scope: Any = "all",
|
|
262
|
-
invoked_project: str = "",
|
|
263
|
-
since_iso: Optional[str] = None,
|
|
264
|
-
limit: int = 0,
|
|
265
|
-
) -> List[SessionDigest]:
|
|
266
|
-
"""Walk ~/.claude/projects and return digests matching scope/time.
|
|
267
|
-
|
|
268
|
-
Parameters
|
|
269
|
-
----------
|
|
270
|
-
transcripts_dir : str ~/.claude/projects
|
|
271
|
-
scope : "all" | "invoked" | list[path]
|
|
272
|
-
invoked_project : str used when scope == "invoked"
|
|
273
|
-
since_iso : str|None ISO8601; only sessions ending after this are kept
|
|
274
|
-
limit : int cap number of digests (0 = no cap)
|
|
275
|
-
"""
|
|
276
|
-
digests: List[SessionDigest] = []
|
|
277
|
-
if not os.path.isdir(transcripts_dir):
|
|
278
|
-
return digests
|
|
279
|
-
|
|
280
|
-
paths: List[str] = []
|
|
281
|
-
for root, _dirs, files in os.walk(transcripts_dir):
|
|
282
|
-
for fn in files:
|
|
283
|
-
if fn.endswith(".jsonl"):
|
|
284
|
-
paths.append(os.path.join(root, fn))
|
|
285
|
-
# newest first by mtime
|
|
286
|
-
paths.sort(key=lambda p: os.path.getmtime(p), reverse=True)
|
|
287
|
-
|
|
288
|
-
for p in paths:
|
|
289
|
-
d = digest_transcript(p)
|
|
290
|
-
if d is None:
|
|
291
|
-
continue
|
|
292
|
-
if _is_headless_replay(d):
|
|
293
|
-
continue # Issue #62: skip engine's own headless replay sessions
|
|
294
|
-
if not _project_matches(d.project or "", scope, invoked_project):
|
|
295
|
-
continue
|
|
296
|
-
if since_iso and d.ended_at and d.ended_at < since_iso:
|
|
297
|
-
# Note: files are sorted by mtime but we compare the embedded
|
|
298
|
-
# ended_at timestamp — mtime can diverge (copy/touch), so we
|
|
299
|
-
# cannot break here; we must continue to check all files.
|
|
300
|
-
continue
|
|
301
|
-
digests.append(d)
|
|
302
|
-
if limit and len(digests) >= limit:
|
|
303
|
-
break
|
|
304
|
-
return digests
|