harvest: user messages wrapped in `<pasted_content …>` are treated as meta, so pasted briefs never become tasks
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 66/100
Hướng nghiên cứu
Start with _is_meta_prompt() in skillopt_sleep/harvest.py (about lines 137-155) and _is_headless_replay() (about lines 217-218), then heuristic_mine() in skillopt_sleep/mine.py (about line 175). Run the synthetic repro in the issue with SKILLOPT_REPO set; it prints which sessions are harvested and each mined intent. Done when the pasted brief is kept as intent, <system-reminder> blocks are stripped, and s2-pasted-only is no longer dropped.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Version examined
microsoft/SkillOptmain@343db229dbd5ddaf9df6b1d5540d8bcdb2604d5c(2026-10-06), packageskillopt_sleep.- Claude Code plugin
skillopt-sleep0.1.0 from the same commit. - Windows 11 Pro (build 26300), Python 3.12.13, plugin runner started from Git Bash 5.3.
- Transcripts written by the Claude Code desktop app (Code tab), version 2.1.271.
Observed behavior
_is_meta_prompt() (skillopt_sleep/harvest.py, lines 137-155) treats any text that starts with < and ends with > as system noise (line 142).
The desktop app stores pasted text in the user message wrapped in a tag pair carrying the same id: <pasted_content id="…"> … </pasted_content id="…">. We verified this on our own transcripts by checking only the opening and closing tag, without exporting their content. A pasted brief is therefore dropped, and it is often the main request of the session.
Three consequences, all reproduced below with synthetic data:
- Wrong intent. If the user then writes a short follow-up such as "Yes, go ahead with option A.", that follow-up becomes the mined task intent, because
heuristic_mine()takes the first surviving prompt (skillopt_sleep/mine.py, line 175). - Session silently lost. If the pasted brief is the only user message,
n_user_turnsis 0._is_headless_replay()(harvest.py, lines 217-218) then classifies the session as one of the engine's own replays, and the whole session is dropped, although it contains real assistant work. - Related. A user message that starts with a host-injected
<system-reminder>…</system-reminder>block and then contains the real request does not end with>, so it is kept, but the reminder block is copied verbatim into the task intent.
In a real run, 2 of 5 hand-picked sessions were mined from the wrong message for reason 1.
Expected behavior
- Treat
<pasted_content …>blocks as user content: strip the wrapper tags and keep the inner text as the user's intent. - Limit the "meta" heuristic to known host and system tags (for example
<command-message>,<command-name>,<local-command-stdout>,<system-reminder>) instead of any text wrapped in angle brackets. - Strip host-injected
<system-reminder>blocks from intents. - Do not classify a session that has real assistant turns as a headless replay only because all its user turns were filtered out.
Minimal synthetic reproduction
No model calls and no network. Run from the repository root, or set SKILLOPT_REPO to it.
"""Synthetic repro: pasted briefs are dropped by the harvest meta filter (no model calls, no network)."""
import json
import os
import sys
import tempfile
sys.path.insert(0, os.environ.get("SKILLOPT_REPO", "."))
from skillopt_sleep.harvest import _is_meta_prompt, harvest # noqa: E402
from skillopt_sleep.mine import heuristic_mine # noqa: E402
ROOT = tempfile.mkdtemp(prefix="skillopt-d19-")
PROJECT = os.path.join(ROOT, "proj")
TRANSCRIPTS = os.path.join(ROOT, "projects")
os.makedirs(PROJECT)
BRIEF = ('<pasted_content id="a1b2">\nInstall tool X into a dedicated folder, pin the version, '
'back up the configs first and write a short report.\n</pasted_content id="a1b2">')
REMINDER = ('<system-reminder>\nStatus note injected by the host app.\n</system-reminder>\n\n'
'Yes: run the third review on range r2..abc1234 and update the report.')
def session(sid, turns):
folder = os.path.join(TRANSCRIPTS, "proj")
os.makedirs(folder, exist_ok=True)
with open(os.path.join(folder, sid + ".jsonl"), "w", encoding="utf-8") as f:
for i, (role, text) in enumerate(turns):
f.write(json.dumps({"type": role, "cwd": PROJECT, "sessionId": sid,
"timestamp": f"2026-01-01T10:{i:02d}:00Z",
"message": {"role": role, "content": text}}) + "\n")
session("s1-pasted-then-followup", [("user", BRIEF), ("assistant", "Plan: ..."),
("user", "Yes, go ahead with option A."), ("assistant", "Done.")])
session("s2-pasted-only", [("user", BRIEF), ("assistant", "Plan: ..."), ("assistant", "Done.")])
session("s3-reminder-prefix", [("user", REMINDER), ("assistant", "Running the review.")])
print("_is_meta_prompt(BRIEF) =", _is_meta_prompt(BRIEF))
digests = harvest(TRANSCRIPTS, scope="invoked", invoked_project=PROJECT)
print("harvested sessions:", sorted(d.session_id for d in digests))
for t in heuristic_mine(digests):
print(f"task from {t.source_sessions[0]}: intent = {t.intent!r}")
Output at the commit above:
_is_meta_prompt(BRIEF) = True
harvested sessions: ['s1-pasted-then-followup', 's3-reminder-prefix']
task from s3-reminder-prefix: intent = '<system-reminder>\nStatus note injected by the host app.\n</system-reminder>\n\nYes: run the third review on range r2..abc1234 and update the report.'
task from s1-pasted-then-followup: intent = 'Yes, go ahead with option A.'
s2-pasted-only is missing from the harvested sessions: the pasted brief was its only user message.
Related
- #99 extended
_is_meta_prompt()to skip expanded slash-command bodies (<command-message>,<command-name>,# /…). - #295 skips records marked
isMeta: trueand leaves the text heuristics of_is_meta_prompt()unchanged. - Neither covers
<pasted_content>: a pasted brief is typed by the user and is not markedisMeta. We found no open or closed issue or PR about it.
Not verified
- Whether the Claude Code terminal CLI, or other clients, use the same
<pasted_content>wrapper. We observed it only in the desktop app. - Whether other host tags that wrap a whole user message exist and are dropped the same way.
- Ngôn ngữ chính
- Python
- Star
- 18.2k
- Fork
- 1.7k
- Merge trung bình
- 4 ngày 1 giờ
- Pull request đã merge (30 ngày)
- 10
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/SkillOpt
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 2 ngày
-
Clarification on Rollout Timeouts, Inference Concurrency, and Their Impact on SkillOpt EvaluationĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 12/100
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 32/100
Maintainer thường phản hồi trong vòng 2 ngày
-
skillopt-sleep: max_tokens_per_night is defaulted and documented but never enforcedCó thể đã có người làm @Thanatos9404 đã nhận 2 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của microsoft/SkillOpt
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
ok-oldking/ok-wuthering-waves#1785 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
healthchecks/healthchecks#1349 ·
-
deployment release-lag
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 68/100
nolte/kamerplanter#2374 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug v1 v2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
modelcontextprotocol/python-sdk#3725 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
batchterms() drops queries without a similar() clause, misaligning results with inputsCó thể đã có người làm @MohammadHijjawi97 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
Maintainer thường phản hồi trong vòng 1 ngày