harvest: user messages wrapped in `<pasted_content …>` are treated as meta, so pasted briefs never become tasks
Los mantenedores suelen responder en 2 días
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 66/100
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Python
- Estrellas
- 18.5k
- Forks
- 1.8k
- Merge medio
- 5 d 18 h
- PR fusionados (30 d)
- 15
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/SkillOpt
-
Dificultad 4/5 3-5 días Aptitud para principiantes 15/100
Los mantenedores suelen responder en 2 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
microsoft/SkillOpt#325 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
harvest: single-turn headless sessions from other local tooling are harvested as user tasks and fill the session capPosiblemente ocupada @SU-AN-coder la tomó hoy. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
microsoft/SkillOpt#319 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
Los mantenedores suelen responder en 2 días
-
Clarification on Rollout Timeouts, Inference Concurrency, and Their Impact on SkillOpt EvaluationAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 12/100
Los mantenedores suelen responder en 2 días
Todos los issues de microsoft/SkillOpt
Issues similares
-
tunneld on Windows: Wi-Fi devices are not discovered because uvicorn runs on a ProactorEventLoopAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
doronz88/pymobiledevice3#2051 ·
Los mantenedores suelen responder en 1 día
-
Remove DatacircleAbierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
collabnix/awesome-mcp-lists#230 ·
Los mantenedores suelen responder en 9 días
-
Groc schedules with out of range values pass config validation and fail later when the scheduler is builtPosiblemente ocupada @auraseb la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
autowarefoundation/autoware_carla_scenario#342 ·
Los mantenedores suelen responder en 1 día
-
documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
ianktoo/project-monitor#14 ·