dsh-open-dream-rsi 0.3.13 → 0.3.15

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.
@@ -46,7 +46,7 @@ from open_dream_rsi.bench_policy import (
46
46
  run_policy_benchmark,
47
47
  )
48
48
 
49
- __version__ = "0.3.13"
49
+ __version__ = "0.3.15"
50
50
 
51
51
  __all__ = [
52
52
  "DiscoveryTree",
@@ -89,7 +89,9 @@ LESSON_CONTRACT = (
89
89
  "objects, each exactly: {{\"trigger\": \"...\", \"text\": \"...\"}}. "
90
90
  "'trigger' is 1-4 lowercase keywords tying the lesson to this failure "
91
91
  "family — separate the keywords with SINGLE SPACES, never commas or "
92
- "semicolons; 'text' is one actionable insight in at most 3000 characters, "
92
+ "semicolons. GOOD: 'pip cache', 'ssh key perms', 'docker compose env'. "
93
+ "BAD (rejected by validation): sentence-like 'traceback code does "
94
+ "not execute' (5 words). 'text' is one actionable insight in at most 3000 characters, "
93
95
  "grounded ONLY in the evidence shown. Be SPECIFIC, not terse: name the "
94
96
  "observable signal (the exact error shape, tool, or state that "
95
97
  "recurs), the mechanism that made the attempt fail, and the bounded "
@@ -139,6 +139,7 @@ def collect(memory_root: "str | Path", hours: Optional[float] = None) -> Dict[st
139
139
  }
140
140
 
141
141
  lessons: Dict[str, Dict[str, int]] = {}
142
+ lesson_usage: List[Dict[str, Any]] = []
142
143
  lessons_path = root / "lessons.json"
143
144
  if lessons_path.exists():
144
145
  try:
@@ -150,6 +151,15 @@ def collect(memory_root: "str | Path", hours: Optional[float] = None) -> Dict[st
150
151
  st = Counter(str(i.get("status", "?")) for i in items if isinstance(i, dict))
151
152
  lessons[cat] = {"active": st.get("active", 0), "staging": st.get("staging", 0),
152
153
  "total": len(items)}
154
+ for i in items:
155
+ if isinstance(i, dict):
156
+ lesson_usage.append({
157
+ "category": cat,
158
+ "trigger": str(i.get("trigger", "")),
159
+ "uses": int(i.get("uses", 0) or 0),
160
+ "wins": int(i.get("wins", 0) or 0),
161
+ "status": str(i.get("status", "?")),
162
+ })
153
163
 
154
164
  recipes: Dict[str, float] = {}
155
165
  recipes_path = root / "recipes.json"
@@ -206,6 +216,7 @@ def collect(memory_root: "str | Path", hours: Optional[float] = None) -> Dict[st
206
216
  "tokens": {"prompt": tokens_prompt, "completion": tokens_completion,
207
217
  "cycles_with_usage": tokens_cycles},
208
218
  "lessons": lessons,
219
+ "lesson_usage": lesson_usage,
209
220
  "recipes": recipes,
210
221
  "outcomes_all_time": outcomes,
211
222
  "backlog": {"queued_tasks": queue_len,
@@ -268,6 +279,22 @@ def format_metrics(data: Dict[str, Any]) -> str:
268
279
  out.append(f" {cat}: {s['active']}/{s['staging']}")
269
280
  else:
270
281
  out.append(" (knowledge base empty)")
282
+ usage = data.get("lesson_usage") or []
283
+ if usage:
284
+ out.append("\nlesson usage (uses -> wins, credit rate; uses/wins come from "
285
+ "record_lesson_usage: surfaced into proposals / task solved):")
286
+ def _dead(u):
287
+ return u["wins"] == 0 and u["uses"] >= 4 # mirrors curator.PRUNE_MIN_USES
288
+ ranked = sorted(usage, key=lambda u: (0 if _dead(u) else 1,
289
+ -u["uses"], -u["wins"], u["trigger"]))
290
+ shown = ranked[:12]
291
+ for u in shown:
292
+ rate = f"{100.0 * u['wins'] / u['uses']:.0f}%" if u["uses"] else "-"
293
+ flag = " <-- dead (>=4 uses, 0 wins)" if _dead(u) else ""
294
+ out.append(f" {u['category']} | {u['trigger']}: {u['uses']} -> "
295
+ f"{u['wins']} ({rate}){flag}")
296
+ if len(ranked) > len(shown):
297
+ out.append(f" ...{len(ranked) - len(shown)} more")
271
298
  recipes = data["recipes"]
272
299
  if recipes:
273
300
  out.append("recipes: " + ", ".join(f"{c}={s:g}" for c, s in sorted(recipes.items())))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-open-dream-rsi",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "Let your coding agent dream: strategies must survive counterfactual replay before they earn trust. An offline self-improvement loop over an evolving world model \u2014 no fine-tuning, the LLM stays frozen. Speaks MCP. Ships its Python server inside the package \u2014 the only requirement is a system python3 (3.10+) on PATH \u2014 and the plugin's bridge serves the dreamer's LLM calls from the model your harness is already configured with (no API keys, no env, no extra endpoints).",
5
5
  "type": "module",
6
6
  "license": "MIT",