Buckets:
| # Thread charts for the Hub agent-traces analysis, Huggiverse sticker style. | |
| # Every number is computed here from hub/sessions_tagged.jsonl and hub/labels.jsonl. | |
| # python3 charts/make_charts.py <scratchpad> | |
| import collections as Cn, html, json, os, pathlib, re, shutil, subprocess, sys, tempfile | |
| S = pathlib.Path(sys.argv[1]) | |
| OUT = S / "charts" / "out"; OUT.mkdir(parents=True, exist_ok=True) | |
| C = dict(bg="#E9E6DD", surface="#FBF8F1", ink="#232323", muted="#8C8C8C", soft="#55524B", yellow="#FFD21E", | |
| orange="#FF9D00", blue="#3B7CF6", red="#EF3E36", purple="#A855F7", green="#3E8E5E", grey="#ECEAE2", | |
| tint_y="#FFF1C6", tint_b="#DCE7FB") | |
| DISPLAY, BODY, MONO = "Chewy, cursive", "'Source Sans 3', sans-serif", "'IBM Plex Mono', monospace" | |
| FONTS = ("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500" | |
| "&family=Source+Sans+3:wght@400;600;700&family=Chewy&display=swap") | |
| CHROME = str(next(pathlib.Path.home().glob("Library/Caches/ms-playwright/chromium-*/chrome-mac-arm64/" | |
| "Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"))) | |
| SIG = "🤗 agent traces" | |
| W, H = 1200, 675 | |
| captions = [] | |
| def text(x, y, s, size=16, font=BODY, fill=C["ink"], anchor="start", weight=400): | |
| return (f'<text x="{x}" y="{y}" font-family="{font}" font-size="{size}" fill="{fill}" ' | |
| f'text-anchor="{anchor}" font-weight="{weight}">{html.escape(str(s))}</text>') | |
| def sticker(x, y, w, h, fill, r=10, shadow=5, sw=2.5): | |
| return (f'<rect x="{x+shadow}" y="{y+shadow}" width="{w}" height="{h}" rx="{r}" fill="{C["ink"]}"/>' | |
| f'<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="{r}" fill="{fill}" stroke="{C["ink"]}" stroke-width="{sw}"/>') | |
| def bar(x, y, w, h, fill): | |
| return f'<rect x="{x}" y="{y}" width="{max(w, 0)}" height="{h}" fill="{fill}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| def frame(title, body, footer, desc): | |
| captions.append({"title": title, "desc": desc}) | |
| s = f'<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{H}" viewBox="0 0 {W} {H}">' | |
| s += f'<rect width="{W}" height="{H}" fill="{C["bg"]}"/>' + sticker(24, 24, W - 56, H - 56, C["surface"], r=16, shadow=7) | |
| s += text(56, 92, title, 42, DISPLAY) + text(W - 56, 88, SIG, 14, MONO, C["muted"], "end") | |
| s += text(56, H - 52, footer, 13, MONO, C["muted"]) | |
| return s + body + "</svg>" | |
| def render(name, svg): | |
| only = os.environ.get("ONLY") | |
| if only and name not in only.split(","): | |
| return | |
| w, h = (round(float(v)) for v in re.search(r'width="([\d.]+)" height="([\d.]+)"', svg).groups()) | |
| (OUT / f"{name}.svg").write_text(svg) | |
| page = f'<!doctype html><meta charset="utf-8"><link rel="stylesheet" href="{FONTS}"><style>body{{margin:0}}</style>{svg}' | |
| with tempfile.TemporaryDirectory() as tmp: | |
| p = pathlib.Path(tmp) / "c.html"; p.write_text(page) | |
| subprocess.run([CHROME, "--headless=new", "--hide-scrollbars", "--force-device-scale-factor=2", | |
| f"--window-size={w},{h}", "--virtual-time-budget=5000", f"--screenshot={OUT / (name + '.png')}", | |
| p.as_uri()], check=True, capture_output=True) | |
| png = OUT / f"{name}.png" | |
| if shutil.which("oxipng"): | |
| subprocess.run(["oxipng", "-q", "-o", "2", "--strip", "safe", str(png)], check=True) | |
| if shutil.which("cwebp"): | |
| subprocess.run(["cwebp", "-lossless", "-z", "9", "-exact", "-quiet", str(png), "-o", str(png.with_suffix(".webp"))], check=True) | |
| print("wrote", png) | |
| def fmt(n): | |
| return f"{n:,}" | |
| sessions = [json.loads(l) for l in open(S / "hub/sessions_tagged.jsonl")] | |
| labels = [json.loads(l) for l in open(S / "hub/labels.jsonl")] | |
| real_ds = {r["dataset"] for r in sessions if r["category"] == "real"} | |
| HARN = [("pi", "pi", C["yellow"]), ("claude-code", "Claude Code", C["orange"]), ("codex", "Codex", C["blue"])] | |
| FOOT = "Hub datasets tagged agent-traces, Oct 2026 · pi complete, Claude Code/Codex ≤ 40 files per dataset · deduped by content" | |
| # 1 — sessions by kind --------------------------------------------------------------------------- | |
| cnt = Cn.Counter(r["category"] for r in sessions if r["category"] != "paper-repro-bot") | |
| real_by_h = Cn.Counter(r["harness"] for r in sessions if r["category"] == "real") | |
| rows = sorted([("synthetic-dump", "One generated prompt per session"), ("real", "People working with an agent"), | |
| ("benchmark/harness", "Benchmark and eval sweeps")], key=lambda x: -cnt[x[0]]) | |
| x0, y0, bw, bh, gap = 420, 170, 640, 64, 52 | |
| mx = max(cnt.values()) | |
| body = "" | |
| for i, (k, lab) in enumerate(rows): | |
| y = y0 + i * (bh + gap) | |
| body += text(x0 - 24, y + bh / 2 + 7, lab, 22, BODY, C["ink"], "end", 600) | |
| if k == "real": | |
| x = x0 | |
| for h, _, col in sorted(HARN, key=lambda t: -real_by_h[t[0]]): | |
| w = bw * real_by_h[h] / mx | |
| body += bar(x, y, w, bh, col); x += w | |
| end = x | |
| else: | |
| end = x0 + bw * cnt[k] / mx | |
| body += bar(x0, y, end - x0, bh, C["grey"]) | |
| body += text(end + 14, y + bh / 2 + 9, fmt(cnt[k]), 28, DISPLAY) | |
| if k == "real": # harness legend on the same row, sorted by value | |
| lx, ly = end + 130, y + bh / 2 + 7 | |
| for h, name, col in sorted(HARN, key=lambda t: -real_by_h[t[0]]): | |
| body += f'<rect x="{lx}" y="{ly - 14}" width="18" height="18" fill="{col}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| lab = f"{name} {fmt(real_by_h[h])}" | |
| body += text(lx + 26, ly, lab, 18, BODY, C["soft"]) | |
| lx += 44 + len(lab) * 8.6 | |
| render("1_sessions_by_kind", frame("Agent sessions on the Hub, by kind", body, | |
| FOOT + " · bot runs excluded", | |
| f"Unique sessions after deduping: {fmt(sum(cnt.values()))}; people working with an agent are {fmt(cnt['real'])}.")) | |
| # 2 — user messages per session -------------------------------------------------------------------- | |
| BUCK = [("1", lambda n: n <= 1, C["grey"]), ("2–5", lambda n: 2 <= n <= 5, C["tint_y"]), | |
| ("6–20", lambda n: 6 <= n <= 20, C["yellow"]), ("> 20", lambda n: n > 20, C["orange"])] | |
| groups = [("People", [r for r in sessions if r["category"] == "real"]), | |
| ("Synthetic", [r for r in sessions if r["category"] == "synthetic-dump"])] | |
| x0, y0, bw, bh, gap = 260, 200, 860, 90, 70 | |
| body = "" | |
| for i, (lab, rs) in enumerate(groups): | |
| y = y0 + i * (bh + gap) | |
| body += text(x0 - 24, y + bh / 2 + 6, lab, 26, BODY, C["ink"], "end", 700) | |
| body += text(x0 - 24, y + bh / 2 + 30, f"{fmt(len(rs))} sessions", 15, MONO, C["muted"], "end") | |
| x = x0 | |
| for name, pred, col in BUCK: | |
| share = sum(pred(r["user_prompts"]) for r in rs) / len(rs) | |
| w = bw * share | |
| body += bar(x, y, w, bh, col) | |
| if w >= 44: | |
| body += text(x + w / 2, y + bh / 2 + 10, f"{round(100 * share)}%", 28, DISPLAY, C["ink"], "middle") | |
| x += w | |
| lx, ly = x0, y0 + 2 * (bh + gap) + 10 | |
| body += text(lx, ly, "user messages per session:", 18, BODY, C["soft"]) | |
| lx += 236 | |
| for name, _, col in BUCK: | |
| body += f'<rect x="{lx}" y="{ly - 15}" width="18" height="18" fill="{col}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| body += text(lx + 26, ly, name, 18, BODY, C["soft"]); lx += 100 | |
| render("2_messages_per_session", frame("User messages per session", body, FOOT, | |
| "Share of sessions by number of user messages: people working with an agent vs one-shot synthetic sessions.")) | |
| # 3 — follow-up kinds ------------------------------------------------------------------------------- | |
| fu = [r for r in labels if r["dataset"] in real_ds and r.get("author") == "human" and r["turn"] > 0] | |
| NAMES = {"new-task": "New request", "correct-redirect": "Correction", "approve-continue": "Approval / continue", | |
| "clarify-answer": "Answering the agent", "complain-frustrated": "Frustration", "n/a": "Unclear"} | |
| COLS = {"new-task": C["blue"], "correct-redirect": C["red"], "approve-continue": C["green"], | |
| "clarify-answer": C["purple"], "complain-frustrated": C["orange"], "n/a": C["grey"]} | |
| fc = Cn.Counter(r.get("followup_kind") for r in fu if r.get("followup_kind") in NAMES) | |
| tot = sum(fc.values()) | |
| x0, y0, bw, bh, gap = 330, 140, 700, 52, 22 | |
| mx = max(fc.values()) | |
| body = "" | |
| for i, (k, v) in enumerate(fc.most_common()): | |
| y = y0 + i * (bh + gap) | |
| body += text(x0 - 22, y + bh / 2 + 8, NAMES[k], 22, BODY, C["ink"], "end", 600) | |
| w = bw * v / mx | |
| body += bar(x0, y, w, bh, COLS[k]) | |
| body += text(x0 + w + 14, y + bh / 2 + 10, f"{round(100 * v / tot)}%", 28, DISPLAY) | |
| render("3_followups", frame("Messages after the first one", body, | |
| f"{fmt(tot)} follow-ups from people's sessions, labelled by GLM-5.3-Flash (≤ 40 prompts per dataset) · Hub agent-traces, Oct 2026", | |
| "What people send after their first message, in sessions of people working with an agent.")) | |
| json.dump(captions, open(OUT / "captions.json", "w"), indent=1, ensure_ascii=False) | |
| # 4 — models in people's sessions --------------------------------------------------------------------- | |
| SWEEP = {"dacorvo/hf-hub-session-pi-traces", "dacorvo/transformers-coding-session-pi-traces"} # same tasks x local models | |
| def model_name(m): | |
| m = re.sub(r"^(hf|huggingface):", "", (m or "").lower()) | |
| m = m.split(":")[0] | |
| m = re.sub(r"^(bedrock/)?(us\.)?(anthropic[./]|openai/|moonshotai/|minimax/|minimaxai/|z-ai/|zai-org/|deepseek/|deepseek-ai/|" | |
| r"qwen/|google/|ggml-org/|unsloth/|tencent/|mlx-community/|nvidia/)", "", m) | |
| m = re.sub(r"-v\d+$|-\d{8}$|-gguf$", "", m).replace("-gguf", "") | |
| m = re.sub(r"(\d)-(\d)(?=$|-)", r"\1.\2", m) | |
| m = re.sub(r"-(instruct|it)(?=$|-)|-qat-q4_0$", "", m) | |
| return m or None | |
| MAKERS = [("gpt", "OpenAI", C["blue"]), ("claude", "Anthropic", C["orange"]), ("deepseek", "DeepSeek", C["purple"]), | |
| ("gemma", "Google", C["green"]), ("qwen", "Qwen", C["red"]), ("glm", "Z.ai", C["yellow"]), | |
| ("kimi", "Moonshot", C["tint_b"]), ("minimax", "MiniMax", C["tint_y"])] | |
| def maker(m): | |
| return next(((n, col) for k, n, col in MAKERS if k in m), ("other", C["grey"])) | |
| real = [r for r in sessions if r["category"] == "real" and model_name(r["model"])] | |
| mc = Cn.Counter(model_name(r["model"]) for r in real) | |
| sweep_share = {m: sum(model_name(r["model"]) == m and r["dataset"] in SWEEP for r in real) / n for m, n in mc.items()} | |
| top = mc.most_common(15) | |
| x0, y0, bw, bh, gap = 340, 130, 640, 22, 9 | |
| mx = top[0][1] | |
| body = ('<defs><pattern id="hatch" width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">' | |
| f'<rect width="3" height="8" fill="{C["ink"]}" opacity=".45"/></pattern></defs>') | |
| by_h = Cn.Counter((model_name(r["model"]), r["harness"], r["dataset"] in SWEEP) for r in real) | |
| for i, (m, v) in enumerate(top): | |
| y = y0 + i * (bh + gap) | |
| body += text(x0 - 18, y + bh / 2 + 6, m, 16, MONO, C["ink"], "end") | |
| x = x0 | |
| for h, _, col in HARN: | |
| for sw in (False, True): | |
| n = by_h[(m, h, sw)] | |
| if not n: | |
| continue | |
| w = bw * n / mx | |
| body += bar(x, y, w, bh, col) | |
| if sw: | |
| body += f'<rect x="{x}" y="{y}" width="{w}" height="{bh}" fill="url(#hatch)" stroke="{C["ink"]}" stroke-width="2"/>' | |
| x += w | |
| body += text(x + 10, y + bh / 2 + 7, fmt(v), 18, DISPLAY) | |
| # legend: harnesses sorted by sessions in the chart; hatch explained | |
| hc = Cn.Counter() | |
| for (m, h, sw), n in by_h.items(): | |
| if m in dict(top): | |
| hc[h] += n | |
| lx, ly = 900, 470 | |
| for h, name, col in sorted(HARN, key=lambda t: -hc[t[0]]): | |
| body += f'<rect x="{lx}" y="{ly - 14}" width="18" height="18" fill="{col}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| body += text(lx + 28, ly, name, 18, BODY, C["soft"]); ly += 27 | |
| body += (f'<rect x="{lx}" y="{ly - 14}" width="18" height="18" fill="url(#hatch)" stroke="{C["ink"]}" stroke-width="2"/>' | |
| + text(lx + 28, ly, "one user replaying", 18, BODY, C["soft"]) + text(lx + 28, ly + 22, "the same tasks", 18, BODY, C["soft"])) | |
| render("4_models", frame("Models in people's agent sessions", body, | |
| f"Main model per session, {fmt(len(real))} sessions of people working with pi / Claude Code / Codex · Hub agent-traces, Oct 2026", | |
| "Sessions per model (top 15), split by harness, people's sessions only; hatched bars come from one user's sweep of the same tasks across local models.")) | |
| json.dump(captions, open(OUT / "captions.json", "w"), indent=1, ensure_ascii=False) | |
| # 5 — what people ask (first message) ----------------------------------------------------------------- | |
| INTENTS = {"build-new": "Build something new", "understand-explain": "Explain / answer about code", | |
| "extend-existing": "Add to existing code", "fix-debug": "Fix a bug or error", | |
| "research-investigate": "Research / investigate", "review-refactor-test": "Review, refactor, test", | |
| "run-ops": "Run, deploy, git, setup", "agent-meta": "Configure the agent", | |
| "write-content": "Write docs or text", "data-ml": "Data analysis / ML experiments", | |
| "steer-followup": "Continue earlier work", "personal-admin": "Email, calendar, todos", | |
| "other": "Greetings, tests, unclear"} | |
| first = [r for r in labels if r["dataset"] in real_ds and r.get("author") == "human" and r["turn"] == 0 | |
| and r.get("intent") in INTENTS] | |
| ic = Cn.Counter(r["intent"] for r in first) | |
| ih = Cn.Counter((r["intent"], r["format"]) for r in first) | |
| tot = len(first) | |
| rows = [k for k, _ in ic.most_common() if k != "other"] + ["other"] # catch-all last | |
| x0, y0, bw, bh, gap = 400, 130, 560, 22, 9 | |
| mx = max(ic.values()) | |
| body = "" | |
| for i, k in enumerate(rows): | |
| y = y0 + i * (bh + gap) | |
| body += text(x0 - 18, y + bh / 2 + 7, INTENTS[k], 18, BODY, C["ink"] if k != "other" else C["muted"], "end", 600) | |
| x = x0 | |
| for h, _, col in HARN: | |
| n = ih[(k, h)] | |
| if n: | |
| w = bw * n / mx | |
| body += bar(x, y, w, bh, col); x += w | |
| pct = 100 * ic[k] / tot | |
| body += text(x + 10, y + bh / 2 + 7, f"{pct:.0f}%" if pct >= 1 else "<1%", 18, DISPLAY) | |
| fh = Cn.Counter(r["format"] for r in first) | |
| lx, ly = 1000, 470 | |
| for h, name, col in sorted(HARN, key=lambda t: -fh[t[0]]): | |
| body += f'<rect x="{lx}" y="{ly - 14}" width="18" height="18" fill="{col}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| body += text(lx + 28, ly, name, 18, BODY, C["soft"]); ly += 27 | |
| render("5_first_requests", frame("What people ask their agents first", body, | |
| f"First message of {fmt(tot)} people's sessions, labelled by GLM-5.3-Flash (≤ 40 prompts per dataset) · Hub agent-traces, Oct 2026", | |
| "Category of the first message in people's agent sessions, split by harness.")) | |
| json.dump(captions, open(OUT / "captions.json", "w"), indent=1, ensure_ascii=False) | |
| # 6 — session size box plots --------------------------------------------------------------------------- | |
| import math | |
| def pct(v, p): | |
| v = sorted(v) | |
| k = (len(v) - 1) * p | |
| lo, hi = math.floor(k), math.ceil(k) | |
| return v[lo] + (v[hi] - v[lo]) * (k - lo) | |
| GROUPS = [(name, col, [r for r in sessions if r["category"] == "real" and r["harness"] == h]) for h, name, col in HARN] | |
| GROUPS.append(("Synthetic", C["grey"], [r for r in sessions if r["category"] == "synthetic-dump"])) | |
| METRICS = [("User messages", lambda r: r["user_prompts"], 100), ("Tool calls", lambda r: r["tool_calls"], 1000), | |
| ("Active minutes", lambda r: r["active_s"] / 60, 1000)] | |
| lab_x, px0, pw, pgap = 200, 236, 258, 52 | |
| ry0, rh = 205, 88 | |
| L = lambda v, top: math.log10(v + 1) / math.log10(top + 1) # log(x+1) so 0 sits on the axis | |
| body = "" | |
| for gi, (gname, col, rs) in enumerate(GROUPS): | |
| cy = ry0 + gi * rh + rh / 2 | |
| body += text(lab_x, cy + 7, gname, 20, BODY, C["ink"] if gname != "Synthetic" else C["muted"], "end", 700) | |
| body += text(lab_x, cy + 27, f"{fmt(len(rs))} sessions", 13, MONO, C["muted"], "end") | |
| for mi, (mname, f, top) in enumerate(METRICS): | |
| x0 = px0 + mi * (pw + pgap) | |
| X = lambda v: x0 + pw * L(v, top) | |
| body += text(x0 + pw / 2, 172, mname, 21, BODY, C["ink"], "middle", 700) | |
| for t in [t for t in (0, 1, 10, 100, 1000) if t <= top]: # axis + light grid | |
| body += f'<line x1="{X(t)}" y1="{ry0 - 4}" x2="{X(t)}" y2="{ry0 + 4 * rh}" stroke="{C["grey"]}" stroke-width="2"/>' | |
| body += text(X(t), ry0 + 4 * rh + 24, "1k" if t == 1000 else t, 14, MONO, C["muted"], "middle") | |
| for gi, (gname, col, rs) in enumerate(GROUPS): | |
| v = [f(r) for r in rs] | |
| p10, p25, p50, p75, p90 = (pct(v, p) for p in (.1, .25, .5, .75, .9)) | |
| cy = ry0 + gi * rh + rh / 2 | |
| body += f'<line x1="{X(p10)}" y1="{cy}" x2="{X(p90)}" y2="{cy}" stroke="{C["ink"]}" stroke-width="2.5"/>' | |
| for e in (p10, p90): | |
| body += f'<line x1="{X(e)}" y1="{cy - 10}" x2="{X(e)}" y2="{cy + 10}" stroke="{C["ink"]}" stroke-width="2.5"/>' | |
| bw_ = max(X(p75) - X(p25), 3) | |
| body += f'<rect x="{X(p25)}" y="{cy - 20}" width="{bw_}" height="40" rx="4" fill="{col}" stroke="{C["ink"]}" stroke-width="2.5"/>' | |
| body += f'<line x1="{X(p50)}" y1="{cy - 20}" x2="{X(p50)}" y2="{cy + 20}" stroke="{C["ink"]}" stroke-width="4"/>' | |
| med = round(p50) if p50 >= 10 else round(p50, 1) | |
| med = int(med) if float(med).is_integer() else med | |
| body += text(X(p50), cy - 27, fmt(med) if isinstance(med, int) else med, 16, DISPLAY, C["ink"], "middle") | |
| render("6_session_size", frame("Session size", body, | |
| "box = 25th–75th percentile · thick line + number = median · whiskers = 10th–90th · log scale · Hub agent-traces, Oct 2026", | |
| "Distribution of user messages, tool calls and active minutes per session, by harness (people's sessions) vs synthetic sessions.")) | |
| json.dump(captions, open(OUT / "captions.json", "w"), indent=1, ensure_ascii=False) | |
| # 7 — tools used ---------------------------------------------------------------------------------------- | |
| TOOL_CATS = [ # first match wins; names differ per harness (bash / Bash / exec_command …) | |
| ("Hugging Face tools", r"^(hf_|hub_|fetch_hf|explore_hf|mcp__huggingface|huggingface_co__|hf_docs|localhost_\d+_mcp__(hf|hub))"), | |
| ("Web & browser", r"web|fetch|search_call|perplexity|browser|playwright|preview_|screenshot|^click$|press_key|type_text|set_value"), | |
| ("Plan / tasks", r"^(task(create|update|stop|list|get)|todo|plan_tool|update_plan|enterplanmode|exitplanmode|update_goal)"), | |
| ("Subagents", r"^(subagent|agent|task|spawn_agent|send_message|wait_agent|list_agents|teams|scout|oracle)$"), | |
| ("Shell", r"^(bash|exec_command|shell_command|shell|exec|execute|powershell|run_command|write_stdin|wait|local_shell_call|js)$"), | |
| ("Read", r"^(read|read_text_file|read_file|view_image|read_session)$"), | |
| ("Edit", r"^(edit|multiedit|apply_patch|edit_file|strreplace)$"), | |
| ("Write", r"^(write|write_text_file)$"), | |
| ("File search", r"^(grep|glob|find|ls|agent__ripgrep\w*)$"), | |
| ] | |
| def tool_cat(name): | |
| n = (name or "").lower() | |
| return next((c for c, rx in TOOL_CATS if re.search(rx, n)), "Other") | |
| tc = {} | |
| for h, _, _ in HARN: | |
| c = Cn.Counter() | |
| for r in sessions: | |
| if r["category"] == "real" and r["harness"] == h: | |
| for t, n in r["tools"].items(): | |
| c[tool_cat(t)] += n | |
| tc[h] = c | |
| share = {h: {k: v / sum(c.values()) for k, v in c.items()} for h, c in tc.items()} | |
| cats = sorted({k for c in tc.values() for k in c}, key=lambda k: -sum(share[h].get(k, 0) for h in share)) | |
| cats = [k for k in cats if k != "Other"] + ["Other"] | |
| lab_x, px0, pw, pgap, ry0, rh = 236, 260, 250, 40, 168, 41 | |
| top_share = max(v for s in share.values() for v in s.values()) | |
| body = "" | |
| for i, k in enumerate(cats): | |
| y = ry0 + i * rh | |
| body += text(lab_x, y + 22, k, 19, BODY, C["muted"] if k == "Other" else C["ink"], "end", 600) | |
| for j, (h, name, col) in enumerate(HARN): | |
| x0 = px0 + j * (pw + pgap) | |
| n = sum(tc[h].values()) | |
| body += text(x0, ry0 - 22, name, 21, BODY, C["ink"], "start", 700) + text(x0 + pw, ry0 - 22, f"{fmt(n)} calls", 13, MONO, C["muted"], "end") | |
| body += f'<line x1="{x0}" y1="{ry0 - 8}" x2="{x0}" y2="{ry0 + len(cats) * rh - 6}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| for i, k in enumerate(cats): | |
| y = ry0 + i * rh | |
| v = share[h].get(k, 0) | |
| w = (pw - 52) * v / top_share | |
| if v > 0: | |
| body += bar(x0, y + 5, w, 26, col) | |
| body += text(x0 + w + 8, y + 25, f"{100 * v:.0f}%" if v >= .01 else ("<1%" if v > 0 else "–"), 17, DISPLAY) | |
| render("7_tools", frame("Tool calls by type", body, | |
| "Share of each harness's tool calls, people's sessions · names grouped by purpose (bash, Bash, exec_command → Shell) · Oct 2026", | |
| "Share of tool calls by type, per harness, in people's sessions.")) | |
| json.dump(captions, open(OUT / "captions.json", "w"), indent=1, ensure_ascii=False) | |
| # 8 — follow-ups by harness -------------------------------------------------------------------------- | |
| fuh = {h: Cn.Counter(r.get("followup_kind") for r in fu if r["format"] == h and r.get("followup_kind") in NAMES) for h, _, _ in HARN} | |
| fshare = {h: {k: v / sum(c.values()) for k, v in c.items()} for h, c in fuh.items()} | |
| kinds = [k for k, _ in fc.most_common() if k != "n/a"] + ["n/a"] # overall order, unclear last | |
| lab_x, px0, pw, pgap, ry0, rh = 236, 260, 250, 40, 190, 62 | |
| top_share = max(v for s in fshare.values() for v in s.values()) | |
| body = "" | |
| for i, k in enumerate(kinds): | |
| body += text(lab_x, ry0 + i * rh + 30, NAMES[k], 20, BODY, C["muted"] if k == "n/a" else C["ink"], "end", 600) | |
| for j, (h, name, col) in enumerate(HARN): | |
| x0 = px0 + j * (pw + pgap) | |
| n = sum(fuh[h].values()) | |
| body += text(x0, ry0 - 26, name, 21, BODY, C["ink"], "start", 700) + text(x0 + pw, ry0 - 26, f"{fmt(n)} follow-ups", 13, MONO, C["muted"], "end") | |
| body += f'<line x1="{x0}" y1="{ry0 - 10}" x2="{x0}" y2="{ry0 + len(kinds) * rh - 10}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| for i, k in enumerate(kinds): | |
| y = ry0 + i * rh | |
| v = fshare[h].get(k, 0) | |
| w = (pw - 56) * v / top_share | |
| if v > 0: | |
| body += bar(x0, y + 8, w, 34, col) | |
| body += text(x0 + w + 8, y + 33, f"{100 * v:.0f}%" if v >= .01 else ("<1%" if v > 0 else "–"), 20, DISPLAY) | |
| render("8_followups_by_harness", frame("Messages after the first one, by harness", body, | |
| "Follow-up messages in people's sessions, labelled by GLM-5.3-Flash (≤ 40 prompts per dataset) · Hub agent-traces, Oct 2026", | |
| "What people send after their first message, per harness.")) | |
| json.dump(captions, open(OUT / "captions.json", "w"), indent=1, ensure_ascii=False) | |
| # 9 — infographic: what people ask, session size, tools, follow-ups ------------------------------------- | |
| IW, IH = 1600, 2100 | |
| real_s = [r for r in sessions if r["category"] == "real"] | |
| synth_s = [r for r in sessions if r["category"] == "synthetic-dump"] | |
| inv = [json.loads(l) for l in open(S / "hub/inventory.jsonl")] | |
| n_authors = len({r["dataset"].split("/")[0] for r in real_s}) | |
| HC = {h: col for h, _, col in HARN} | |
| def swatch(x, y, col, s=18): | |
| return f'<rect x="{x}" y="{y - s + 3}" width="{s}" height="{s}" rx="3" fill="{col}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| def panel(x, y, w, h, num, title, badge): | |
| s = sticker(x, y, w, h, C["surface"], r=16, shadow=7) | |
| s += f'<circle cx="{x + 46}" cy="{y + 50}" r="24" fill="{C["yellow"]}" stroke="{C["ink"]}" stroke-width="2.5"/>' | |
| s += text(x + 46, y + 61, num, 30, DISPLAY, C["ink"], "middle") | |
| s += text(x + 84, y + 62, title, 34, DISPLAY) | |
| bw_ = 26 + len(badge) * 9.4 | |
| s += sticker(x + 28, y + h - 74, bw_, 44, C["tint_y"], r=22, shadow=3, sw=2) | |
| s += text(x + 28 + 18, y + h - 45, badge, 19, BODY, C["ink"], "start", 700) | |
| return s | |
| svg = f'<svg xmlns="http://www.w3.org/2000/svg" width="{IW}" height="{IH}" viewBox="0 0 {IW} {IH}"><rect width="{IW}" height="{IH}" fill="{C["bg"]}"/>' | |
| svg += text(64, 112, "What people do with their coding agents", 66, DISPLAY) + text(IW - 64, 104, SIG, 16, MONO, C["muted"], "end") | |
| # stat strip | |
| stats = [(fmt(len(inv)), "agent-trace datasets on the Hub"), (f"{len(sessions) / 1000:.1f}k", "unique sessions after dedup"), | |
| (fmt(len(real_s)), f"of them are people at work ({100 * len(real_s) / len(sessions):.0f}%)"), | |
| (str(n_authors), "authors behind those sessions")] | |
| sw_, gap_ = (IW - 128 - 3 * 28) / 4, 28 | |
| for i, (big, lab) in enumerate(stats): | |
| x = 64 + i * (sw_ + gap_) | |
| svg += sticker(x, 150, sw_, 128, C["yellow"] if i == 2 else C["surface"], r=14, shadow=6) | |
| svg += text(x + 26, 222, big, 58, DISPLAY) + text(x + 26, 256, lab, 18, BODY, C["soft"], "start", 600) | |
| # harness key | |
| lx = 64 | |
| svg += text(lx, 330, "Panels show people's sessions, by harness:", 20, BODY, C["soft"], "start", 600); lx += 400 | |
| for h, name, col in HARN: | |
| n = sum(r["harness"] == h for r in real_s) | |
| lab = f"{name} ({fmt(n)})" | |
| svg += swatch(lx, 330, col) + text(lx + 28, 330, lab, 20, BODY, C["ink"], "start", 600); lx += 28 + len(lab) * 9.6 + 40 | |
| svg += swatch(lx, 330, C["grey"]) + text(lx + 28, 330, "synthetic, for reference", 20, BODY, C["muted"], "start", 600) | |
| PX, PY, PW, PH, PG = 64, 372, (IW - 128 - 36) / 2, 800, 36 | |
| cells = [(PX, PY), (PX + PW + PG, PY), (PX, PY + PH + PG), (PX + PW + PG, PY + PH + PG)] | |
| # panel 1 — what they ask first (stacked by harness, % of first messages) | |
| x, y = cells[0] | |
| pct_ = lambda k: 100 * ic[k] / len(first) | |
| pfmt = lambda v: f"{v:.0f}%" if v >= 1 else "<1%" | |
| svg += panel(x, y, PW, PH, 1, "What they ask first", f"{pfmt(pct_('build-new'))} build something new · {pfmt(pct_('personal-admin'))} email, calendar or todos") | |
| rows1 = [k for k, _ in ic.most_common() if k not in ("other",)][:9] + ["other"] | |
| bx, by, bmax, rh1 = x + 300, y + 116, PW - 300 - 80, 55 | |
| for i, k in enumerate(rows1): | |
| yy = by + i * rh1 | |
| svg += text(bx - 16, yy + 25, INTENTS[k], 19, BODY, C["muted"] if k == "other" else C["ink"], "end", 600) | |
| xx = bx | |
| for h, _, col in HARN: | |
| n = ih[(k, h)] | |
| if n: | |
| w = bmax * n / max(ic.values()) | |
| svg += bar(xx, yy + 6, w, 28, col); xx += w | |
| svg += text(xx + 10, yy + 28, f"{pct_(k):.0f}%" if pct_(k) >= 1 else "<1%", 21, DISPLAY) | |
| svg += text(x + 28, y + PH - 92, f"first message of {fmt(len(first))} labelled sessions", 14, MONO, C["muted"]) | |
| # panel 2 — session size (medians + boxes, log scale) | |
| x, y = cells[1] | |
| syn_tools = pct([r["tool_calls"] for r in synth_s], .5) | |
| real_tools = pct([r["tool_calls"] for r in real_s], .5) | |
| svg += panel(x, y, PW, PH, 2, "How big sessions are", f"median tool calls: {real_tools:.0f} for people vs {syn_tools:.0f} for synthetic") | |
| groups2 = [(h, HC[h], [r for r in real_s if r["harness"] == h]) for h, _, _ in HARN] + [("synthetic", C["grey"], synth_s)] | |
| mets = [("User messages", lambda r: r["user_prompts"], 100), ("Tool calls", lambda r: r["tool_calls"], 1000), | |
| ("Active minutes", lambda r: r["active_s"] / 60, 1000)] | |
| ax0, aw = x + 70, PW - 140 | |
| for mi, (mname, f, top) in enumerate(mets): | |
| yy0 = y + 112 + mi * 196 | |
| svg += text(x + 40, yy0 + 8, mname, 22, BODY, C["ink"], "start", 700) | |
| X = lambda v: ax0 + aw * L(v, top) | |
| for t in [t for t in (0, 1, 10, 100, 1000) if t <= top]: | |
| svg += f'<line x1="{X(t)}" y1="{yy0 + 22}" x2="{X(t)}" y2="{yy0 + 160}" stroke="{C["grey"]}" stroke-width="2"/>' | |
| svg += text(X(t), yy0 + 180, "1k" if t == 1000 else t, 14, MONO, C["muted"], "middle") | |
| for gi, (g, col, rs) in enumerate(groups2): | |
| v = [f(r) for r in rs] | |
| p10, p25, p50, p75, p90 = (pct(v, p) for p in (.1, .25, .5, .75, .9)) | |
| cy = yy0 + 40 + gi * 33 | |
| svg += f'<line x1="{X(p10)}" y1="{cy}" x2="{X(p90)}" y2="{cy}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| svg += f'<rect x="{X(p25)}" y="{cy - 12}" width="{max(X(p75) - X(p25), 3)}" height="24" rx="3" fill="{col}" stroke="{C["ink"]}" stroke-width="2"/>' | |
| svg += f'<line x1="{X(p50)}" y1="{cy - 12}" x2="{X(p50)}" y2="{cy + 12}" stroke="{C["ink"]}" stroke-width="3.5"/>' | |
| med = round(p50) if p50 >= 10 else round(p50, 1) | |
| med = int(med) if float(med).is_integer() else med | |
| svg += text(X(p90) + 12, cy + 7, f"median {med}", 15, MONO, C["soft"]) | |
| svg += text(x + 28, y + PH - 92, "box 25–75th pct · line median · whiskers 10–90th · log scale", 14, MONO, C["muted"]) | |
| # panel 3 — tools (grouped bars, share of each harness's calls) | |
| x, y = cells[2] | |
| svg += panel(x, y, PW, PH, 3, "Which tools agents call", f"{100 * share['codex']['Shell']:.0f}% of Codex tool calls are shell commands") | |
| merge = {"File search": "Other", "Subagents": "Other"} | |
| sh3 = {h: Cn.Counter() for h in share} | |
| for h, d in share.items(): | |
| for k, v in d.items(): | |
| sh3[h][merge.get(k, k)] += v | |
| cats3 = [k for k in sorted({k for d in sh3.values() for k in d}, key=lambda k: -sum(sh3[h][k] for h in sh3)) if k != "Other"] + ["Other"] | |
| bx, by, bmax, rh3 = x + 260, y + 112, PW - 260 - 90, 69 | |
| top3 = max(v for d in sh3.values() for v in d.values()) | |
| for i, k in enumerate(cats3): | |
| yy = by + i * rh3 | |
| svg += text(bx - 16, yy + 36, k, 19, BODY, C["muted"] if k == "Other" else C["ink"], "end", 600) | |
| for j, (h, _, col) in enumerate(HARN): | |
| v = sh3[h][k] | |
| w = bmax * v / top3 | |
| svg += bar(bx, yy + 6 + j * 19, max(w, 1.5), 15, col) | |
| svg += text(bx + max(w, 1.5) + 8, yy + 19 + j * 19, f"{100 * v:.0f}%" if v >= .01 else "<1%", 15, DISPLAY) | |
| svg += text(x + 28, y + PH - 92, "share of each harness's tool calls · names grouped by purpose", 14, MONO, C["muted"]) | |
| # panel 4 — follow-ups (grouped bars per harness) | |
| x, y = cells[3] | |
| corr = 100 * fc["correct-redirect"] / sum(fc.values()) | |
| svg += panel(x, y, PW, PH, 4, "What they say next", f"{corr:.0f}% of follow-ups correct the agent") | |
| kinds4 = [k for k, _ in fc.most_common() if k != "n/a"] | |
| bx, by, bmax, rh4 = x + 270, y + 120, PW - 270 - 90, 104 | |
| top4 = max(fshare[h].get(k, 0) for h in fshare for k in kinds4) | |
| for i, k in enumerate(kinds4): | |
| yy = by + i * rh4 | |
| svg += text(bx - 16, yy + 46, NAMES[k], 21, BODY, C["ink"], "end", 600) | |
| for j, (h, _, col) in enumerate(HARN): | |
| v = fshare[h].get(k, 0) | |
| w = bmax * v / top4 | |
| svg += bar(bx, yy + 6 + j * 27, max(w, 1.5), 21, col) | |
| svg += text(bx + max(w, 1.5) + 8, yy + 23 + j * 27, f"{100 * v:.0f}%" if v >= .01 else "<1%", 18, DISPLAY) | |
| svg += text(x + 28, y + PH - 92, f"{fmt(sum(fc.values()))} follow-up messages, share within each harness", 14, MONO, C["muted"]) | |
| svg += text(64, IH - 44, "Hub datasets tagged agent-traces, Oct 2026 · pi complete, Claude Code/Codex ≤ 40 files per dataset · deduped by content", 14, MONO, C["muted"]) | |
| svg += text(64, IH - 22, "People's sessions = multi-turn, not templated · requests & follow-ups labelled by GLM-5.3-Flash (≤ 40 prompts per dataset)", 14, MONO, C["muted"]) | |
| svg += "</svg>" | |
| render("9_infographic", svg) | |
Xet Storage Details
- Size:
- 30.8 kB
- Xet hash:
- 5d91b9d70a1fde9f5d45b97d83d22335510103f069f5e40cd658d7e515d32a65
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.