mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-10-20 05:15:31 +00:00
Merge feat/opentui-native-engine into feat/opentui-memory-window
Brings the memory-window branch current with the base PR: multi-click already in; adds OSC window title/notifications, +10 tree-sitter languages, /sessions this-directory grouping + TUI cwd persistence, and the node26-fnm-discovery + launch-cwd fix. All ui-opentui/gateway/launcher additions; windowing files are ours alone. # Conflicts: # ui-opentui/src/entry/main.tsx
This commit is contained in:
commit
2a28bbcc72
61 changed files with 19867 additions and 8 deletions
526
bench/results/2026-06-12T0412-f0ec24a-gate-ink-ink-r0.json
Normal file
526
bench/results/2026-06-12T0412-f0ec24a-gate-ink-ink-r0.json
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "gate",
|
||||
"ui": "ink",
|
||||
"config": "ink",
|
||||
"mode": "digest",
|
||||
"rep": 0,
|
||||
"run_id": "mqaeu4s1-5kii",
|
||||
"utc": "2026-06-12T04:12:13.105Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": null,
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": null,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-300.ndjson",
|
||||
"msgs": 300,
|
||||
"sha256": "ac81e975c299da7d50cfda7fc0fee33c356bd31a4e17a7f0f8e49905e205051a"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 131301,
|
||||
"gw_pid": 131317,
|
||||
"cgroup": null,
|
||||
"load_avg_at_start": [
|
||||
0.86,
|
||||
3.18,
|
||||
2.1
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 28,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 57968,
|
||||
"pss_kb": 32819,
|
||||
"private_dirty_kb": 20836,
|
||||
"vmhwm_kb": 58048,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 1
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1036,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 6685,
|
||||
"pty_writes": 11,
|
||||
"rss_kb": 110740,
|
||||
"pss_kb": 71656,
|
||||
"private_dirty_kb": 52440,
|
||||
"vmhwm_kb": 110740,
|
||||
"utime_ticks": 24,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1490,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 10222,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 130316,
|
||||
"pss_kb": 91080,
|
||||
"private_dirty_kb": 71084,
|
||||
"vmhwm_kb": 130432,
|
||||
"utime_ticks": 34,
|
||||
"stime_ticks": 4
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1541,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 18217,
|
||||
"pty_writes": 17,
|
||||
"rss_kb": 158520,
|
||||
"pss_kb": 119167,
|
||||
"private_dirty_kb": 99160,
|
||||
"vmhwm_kb": 158596,
|
||||
"utime_ticks": 44,
|
||||
"stime_ticks": 4
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1566,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 21202,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 170104,
|
||||
"pss_kb": 130703,
|
||||
"private_dirty_kb": 110680,
|
||||
"vmhwm_kb": 170108,
|
||||
"utime_ticks": 48,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 1567,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 21202,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 170108,
|
||||
"pss_kb": 130707,
|
||||
"private_dirty_kb": 110684,
|
||||
"vmhwm_kb": 170108,
|
||||
"utime_ticks": 49,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2043,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 32782,
|
||||
"pty_writes": 26,
|
||||
"rss_kb": 176524,
|
||||
"pss_kb": 137064,
|
||||
"private_dirty_kb": 117036,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 61,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3052,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 32872,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 176536,
|
||||
"pss_kb": 137076,
|
||||
"private_dirty_kb": 117048,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 61,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4067,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 32962,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 176544,
|
||||
"pss_kb": 137084,
|
||||
"private_dirty_kb": 117056,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 61,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5068,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33052,
|
||||
"pty_writes": 32,
|
||||
"rss_kb": 176552,
|
||||
"pss_kb": 137092,
|
||||
"private_dirty_kb": 117064,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 61,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6077,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33142,
|
||||
"pty_writes": 34,
|
||||
"rss_kb": 176560,
|
||||
"pss_kb": 137100,
|
||||
"private_dirty_kb": 117072,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 61,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7081,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33232,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 176572,
|
||||
"pss_kb": 137112,
|
||||
"private_dirty_kb": 117084,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 62,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 8087,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33322,
|
||||
"pty_writes": 38,
|
||||
"rss_kb": 176580,
|
||||
"pss_kb": 137120,
|
||||
"private_dirty_kb": 117092,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 62,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 9101,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33412,
|
||||
"pty_writes": 40,
|
||||
"rss_kb": 176584,
|
||||
"pss_kb": 137124,
|
||||
"private_dirty_kb": 117096,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 62,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 10106,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33502,
|
||||
"pty_writes": 42,
|
||||
"rss_kb": 176584,
|
||||
"pss_kb": 137124,
|
||||
"private_dirty_kb": 117096,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 11112,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33622,
|
||||
"pty_writes": 44,
|
||||
"rss_kb": 176596,
|
||||
"pss_kb": 137136,
|
||||
"private_dirty_kb": 117108,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 12114,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33731,
|
||||
"pty_writes": 46,
|
||||
"rss_kb": 176600,
|
||||
"pss_kb": 137140,
|
||||
"private_dirty_kb": 117112,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 13116,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33821,
|
||||
"pty_writes": 48,
|
||||
"rss_kb": 176604,
|
||||
"pss_kb": 137144,
|
||||
"private_dirty_kb": 117116,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 14124,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33911,
|
||||
"pty_writes": 50,
|
||||
"rss_kb": 176620,
|
||||
"pss_kb": 137160,
|
||||
"private_dirty_kb": 117132,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 15135,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34001,
|
||||
"pty_writes": 52,
|
||||
"rss_kb": 177056,
|
||||
"pss_kb": 137596,
|
||||
"private_dirty_kb": 117568,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 16143,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34091,
|
||||
"pty_writes": 54,
|
||||
"rss_kb": 177064,
|
||||
"pss_kb": 137604,
|
||||
"private_dirty_kb": 117576,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 16679,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 34181,
|
||||
"pty_writes": 56,
|
||||
"rss_kb": 177064,
|
||||
"pss_kb": 137604,
|
||||
"private_dirty_kb": 117576,
|
||||
"vmhwm_kb": 182800,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 17152,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 44856,
|
||||
"pty_writes": 63,
|
||||
"rss_kb": 183504,
|
||||
"pss_kb": 144044,
|
||||
"private_dirty_kb": 124016,
|
||||
"vmhwm_kb": 183504,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 18156,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 48502,
|
||||
"pty_writes": 66,
|
||||
"rss_kb": 186292,
|
||||
"pss_kb": 146832,
|
||||
"private_dirty_kb": 126804,
|
||||
"vmhwm_kb": 186292,
|
||||
"utime_ticks": 70,
|
||||
"stime_ticks": 6
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 227
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "commands.catalog",
|
||||
"t_ms": 227
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "setup.status",
|
||||
"t_ms": 227
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 1739
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 3251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 4738
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 5242
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 6250
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 7758
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 9249
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 10254
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 10758
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 12263
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 13746
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 15259
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 15259
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 16743
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 16794
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 17198
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 18254
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 18291
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 300,
|
||||
"events_streamed": 1051,
|
||||
"pty_bytes_total": 48954,
|
||||
"pty_data_callbacks": 71,
|
||||
"first_byte_ms": 99,
|
||||
"session_create_ms": 252,
|
||||
"stream_start_ms": 1439,
|
||||
"vmhwm_kb": 186292,
|
||||
"cg_peak": null,
|
||||
"drain_max_loop_lag_ms": 8,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": "0f62155086e89590f62e059cc7bcf0851b6c88dac942a8f2303ac905481dea48"
|
||||
},
|
||||
"digest_text": "Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit┃exercitationincididuntdolorproidentvelitlaborismagnaamet.─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯│┃Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit│exercitationincididuntdolorproidentvelitlaborismagnaamet.┃─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯768"
|
||||
}
|
||||
526
bench/results/2026-06-12T0412-f0ec24a-gate-ink-ink-r1.json
Normal file
526
bench/results/2026-06-12T0412-f0ec24a-gate-ink-ink-r1.json
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "gate",
|
||||
"ui": "ink",
|
||||
"config": "ink",
|
||||
"mode": "digest",
|
||||
"rep": 1,
|
||||
"run_id": "mqaeuqq6-w5nl",
|
||||
"utc": "2026-06-12T04:12:41.551Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": null,
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": null,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-300.ndjson",
|
||||
"msgs": 300,
|
||||
"sha256": "ac81e975c299da7d50cfda7fc0fee33c356bd31a4e17a7f0f8e49905e205051a"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 132910,
|
||||
"gw_pid": 132934,
|
||||
"cgroup": null,
|
||||
"load_avg_at_start": [
|
||||
1.38,
|
||||
3.07,
|
||||
2.1
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 26,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 57172,
|
||||
"pss_kb": 31971,
|
||||
"private_dirty_kb": 20056,
|
||||
"vmhwm_kb": 57172,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1029,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 6665,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 110572,
|
||||
"pss_kb": 71418,
|
||||
"private_dirty_kb": 52096,
|
||||
"vmhwm_kb": 110572,
|
||||
"utime_ticks": 24,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1456,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 10756,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 123240,
|
||||
"pss_kb": 83980,
|
||||
"private_dirty_kb": 63976,
|
||||
"vmhwm_kb": 123256,
|
||||
"utime_ticks": 29,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1530,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 17854,
|
||||
"pty_writes": 17,
|
||||
"rss_kb": 153588,
|
||||
"pss_kb": 114117,
|
||||
"private_dirty_kb": 94008,
|
||||
"vmhwm_kb": 153612,
|
||||
"utime_ticks": 42,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1582,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 21780,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 183452,
|
||||
"pss_kb": 143933,
|
||||
"private_dirty_kb": 123808,
|
||||
"vmhwm_kb": 183828,
|
||||
"utime_ticks": 53,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 1585,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 21780,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 184052,
|
||||
"pss_kb": 144533,
|
||||
"private_dirty_kb": 124408,
|
||||
"vmhwm_kb": 184368,
|
||||
"utime_ticks": 53,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2033,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33500,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 183660,
|
||||
"pss_kb": 144141,
|
||||
"private_dirty_kb": 124016,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3039,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33590,
|
||||
"pty_writes": 24,
|
||||
"rss_kb": 183680,
|
||||
"pss_kb": 144161,
|
||||
"private_dirty_kb": 124036,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4045,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33680,
|
||||
"pty_writes": 26,
|
||||
"rss_kb": 183684,
|
||||
"pss_kb": 144164,
|
||||
"private_dirty_kb": 124040,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5046,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33770,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 183684,
|
||||
"pss_kb": 144165,
|
||||
"private_dirty_kb": 124040,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6047,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33860,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 183688,
|
||||
"pss_kb": 144169,
|
||||
"private_dirty_kb": 124044,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7057,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33950,
|
||||
"pty_writes": 32,
|
||||
"rss_kb": 183688,
|
||||
"pss_kb": 144169,
|
||||
"private_dirty_kb": 124044,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 8065,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34040,
|
||||
"pty_writes": 34,
|
||||
"rss_kb": 183692,
|
||||
"pss_kb": 144173,
|
||||
"private_dirty_kb": 124048,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 9067,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34130,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 183692,
|
||||
"pss_kb": 144173,
|
||||
"private_dirty_kb": 124048,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 10078,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34220,
|
||||
"pty_writes": 38,
|
||||
"rss_kb": 183692,
|
||||
"pss_kb": 144173,
|
||||
"private_dirty_kb": 124048,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 11085,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34340,
|
||||
"pty_writes": 40,
|
||||
"rss_kb": 183700,
|
||||
"pss_kb": 144181,
|
||||
"private_dirty_kb": 124056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 12088,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34449,
|
||||
"pty_writes": 42,
|
||||
"rss_kb": 183700,
|
||||
"pss_kb": 144181,
|
||||
"private_dirty_kb": 124056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 13092,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34539,
|
||||
"pty_writes": 44,
|
||||
"rss_kb": 183700,
|
||||
"pss_kb": 144181,
|
||||
"private_dirty_kb": 124056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 14098,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34629,
|
||||
"pty_writes": 46,
|
||||
"rss_kb": 183700,
|
||||
"pss_kb": 144181,
|
||||
"private_dirty_kb": 124056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 15104,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34719,
|
||||
"pty_writes": 48,
|
||||
"rss_kb": 183700,
|
||||
"pss_kb": 144181,
|
||||
"private_dirty_kb": 124056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 16112,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34809,
|
||||
"pty_writes": 50,
|
||||
"rss_kb": 183700,
|
||||
"pss_kb": 144181,
|
||||
"private_dirty_kb": 124056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 16668,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 34854,
|
||||
"pty_writes": 51,
|
||||
"rss_kb": 183704,
|
||||
"pss_kb": 144185,
|
||||
"private_dirty_kb": 124060,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 68,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 17123,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 45574,
|
||||
"pty_writes": 58,
|
||||
"rss_kb": 186688,
|
||||
"pss_kb": 147169,
|
||||
"private_dirty_kb": 127044,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 75,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 18132,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 49220,
|
||||
"pty_writes": 61,
|
||||
"rss_kb": 186700,
|
||||
"pss_kb": 147181,
|
||||
"private_dirty_kb": 127056,
|
||||
"vmhwm_kb": 187952,
|
||||
"utime_ticks": 76,
|
||||
"stime_ticks": 7
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "commands.catalog",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "setup.status",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 225
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 1729
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 3237
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 4743
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 5243
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 6227
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 7734
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 9245
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 10228
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 10733
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 12238
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 13744
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 15229
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 15229
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 16737
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 16789
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 17172
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 18234
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 18281
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 300,
|
||||
"events_streamed": 1051,
|
||||
"pty_bytes_total": 49672,
|
||||
"pty_data_callbacks": 74,
|
||||
"first_byte_ms": 101,
|
||||
"session_create_ms": 225,
|
||||
"stream_start_ms": 1428,
|
||||
"vmhwm_kb": 187952,
|
||||
"cg_peak": null,
|
||||
"drain_max_loop_lag_ms": 4,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": "6a921c7981a564ea92adf567c2e55945775a32f52325bb0f05db395af665ba04"
|
||||
},
|
||||
"digest_text": "Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit┃exercitationincididuntdolorproidentvelitlaborismagnaamet.─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯│┃7Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit│exercitationincididuntdolorproidentvelitlaborismagnaamet.┃─ ready │ fake model │ 17s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯68"
|
||||
}
|
||||
526
bench/results/2026-06-12T0422-f0ec24a-gate-ink-ink-r0.json
Normal file
526
bench/results/2026-06-12T0422-f0ec24a-gate-ink-ink-r0.json
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "gate",
|
||||
"ui": "ink",
|
||||
"config": "ink",
|
||||
"mode": "digest",
|
||||
"rep": 0,
|
||||
"run_id": "mqaf74nt-gznn",
|
||||
"utc": "2026-06-12T04:22:19.481Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": null,
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": null,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-300.ndjson",
|
||||
"msgs": 300,
|
||||
"sha256": "ac81e975c299da7d50cfda7fc0fee33c356bd31a4e17a7f0f8e49905e205051a"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 165899,
|
||||
"gw_pid": 165908,
|
||||
"cgroup": null,
|
||||
"load_avg_at_start": [
|
||||
0.29,
|
||||
1.01,
|
||||
1.47
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 27,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 47056,
|
||||
"pss_kb": 21937,
|
||||
"private_dirty_kb": 9948,
|
||||
"vmhwm_kb": 47056,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1033,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 6685,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 111652,
|
||||
"pss_kb": 74425,
|
||||
"private_dirty_kb": 53188,
|
||||
"vmhwm_kb": 111652,
|
||||
"utime_ticks": 24,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1461,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 10768,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 124184,
|
||||
"pss_kb": 86902,
|
||||
"private_dirty_kb": 64996,
|
||||
"vmhwm_kb": 124312,
|
||||
"utime_ticks": 29,
|
||||
"stime_ticks": 4
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1538,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 17881,
|
||||
"pty_writes": 17,
|
||||
"rss_kb": 158184,
|
||||
"pss_kb": 120650,
|
||||
"private_dirty_kb": 98616,
|
||||
"vmhwm_kb": 158236,
|
||||
"utime_ticks": 42,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1563,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 21807,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 173012,
|
||||
"pss_kb": 135435,
|
||||
"private_dirty_kb": 113380,
|
||||
"vmhwm_kb": 173300,
|
||||
"utime_ticks": 48,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 1565,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 21807,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 173764,
|
||||
"pss_kb": 136187,
|
||||
"private_dirty_kb": 114132,
|
||||
"vmhwm_kb": 174096,
|
||||
"utime_ticks": 48,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2042,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33524,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 180232,
|
||||
"pss_kb": 142623,
|
||||
"private_dirty_kb": 120600,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 62,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3047,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33614,
|
||||
"pty_writes": 24,
|
||||
"rss_kb": 180236,
|
||||
"pss_kb": 142627,
|
||||
"private_dirty_kb": 120604,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4051,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33704,
|
||||
"pty_writes": 26,
|
||||
"rss_kb": 180240,
|
||||
"pss_kb": 142631,
|
||||
"private_dirty_kb": 120608,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5056,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33794,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 180244,
|
||||
"pss_kb": 142635,
|
||||
"private_dirty_kb": 120612,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6075,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33884,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 180248,
|
||||
"pss_kb": 142639,
|
||||
"private_dirty_kb": 120616,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 63,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7088,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 33974,
|
||||
"pty_writes": 32,
|
||||
"rss_kb": 180248,
|
||||
"pss_kb": 142639,
|
||||
"private_dirty_kb": 120616,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 8107,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34064,
|
||||
"pty_writes": 34,
|
||||
"rss_kb": 180256,
|
||||
"pss_kb": 142647,
|
||||
"private_dirty_kb": 120624,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 9124,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34154,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 180256,
|
||||
"pss_kb": 142647,
|
||||
"private_dirty_kb": 120624,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 10131,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34244,
|
||||
"pty_writes": 38,
|
||||
"rss_kb": 180264,
|
||||
"pss_kb": 142655,
|
||||
"private_dirty_kb": 120632,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 11142,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34364,
|
||||
"pty_writes": 40,
|
||||
"rss_kb": 180264,
|
||||
"pss_kb": 142655,
|
||||
"private_dirty_kb": 120632,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 12155,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34473,
|
||||
"pty_writes": 42,
|
||||
"rss_kb": 180264,
|
||||
"pss_kb": 142655,
|
||||
"private_dirty_kb": 120632,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 13165,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34563,
|
||||
"pty_writes": 44,
|
||||
"rss_kb": 180264,
|
||||
"pss_kb": 142655,
|
||||
"private_dirty_kb": 120632,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 14172,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34653,
|
||||
"pty_writes": 46,
|
||||
"rss_kb": 180264,
|
||||
"pss_kb": 142576,
|
||||
"private_dirty_kb": 120632,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 15184,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34743,
|
||||
"pty_writes": 48,
|
||||
"rss_kb": 180264,
|
||||
"pss_kb": 142655,
|
||||
"private_dirty_kb": 120632,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 16197,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34833,
|
||||
"pty_writes": 50,
|
||||
"rss_kb": 180268,
|
||||
"pss_kb": 142659,
|
||||
"private_dirty_kb": 120636,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 16672,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 34923,
|
||||
"pty_writes": 52,
|
||||
"rss_kb": 180276,
|
||||
"pss_kb": 142667,
|
||||
"private_dirty_kb": 120644,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 17209,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 45598,
|
||||
"pty_writes": 58,
|
||||
"rss_kb": 181952,
|
||||
"pss_kb": 144343,
|
||||
"private_dirty_kb": 122320,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 72,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 18215,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 49244,
|
||||
"pty_writes": 61,
|
||||
"rss_kb": 182028,
|
||||
"pss_kb": 144420,
|
||||
"private_dirty_kb": 122396,
|
||||
"vmhwm_kb": 187988,
|
||||
"utime_ticks": 74,
|
||||
"stime_ticks": 7
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 228
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "commands.catalog",
|
||||
"t_ms": 228
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "setup.status",
|
||||
"t_ms": 253
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 253
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 253
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 253
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 253
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 1762
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 3246
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 4753
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 5256
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 6249
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 7746
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 9247
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 10257
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 10764
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 12254
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 13740
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 15258
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 15258
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 16752
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 16777
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 17182
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 18263
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 18286
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 300,
|
||||
"events_streamed": 1051,
|
||||
"pty_bytes_total": 49696,
|
||||
"pty_data_callbacks": 67,
|
||||
"first_byte_ms": 115,
|
||||
"session_create_ms": 253,
|
||||
"stream_start_ms": 1435,
|
||||
"vmhwm_kb": 187988,
|
||||
"cg_peak": null,
|
||||
"drain_max_loop_lag_ms": 3,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": "0f62155086e89590f62e059cc7bcf0851b6c88dac942a8f2303ac905481dea48"
|
||||
},
|
||||
"digest_text": "Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit┃exercitationincididuntdolorproidentvelitlaborismagnaamet.─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯│┃Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit│exercitationincididuntdolorproidentvelitlaborismagnaamet.┃─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯768"
|
||||
}
|
||||
526
bench/results/2026-06-12T0422-f0ec24a-gate-ink-ink-r1.json
Normal file
526
bench/results/2026-06-12T0422-f0ec24a-gate-ink-ink-r1.json
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "gate",
|
||||
"ui": "ink",
|
||||
"config": "ink",
|
||||
"mode": "digest",
|
||||
"rep": 1,
|
||||
"run_id": "mqaf7qlt-11yq",
|
||||
"utc": "2026-06-12T04:22:47.921Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": null,
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": null,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-300.ndjson",
|
||||
"msgs": 300,
|
||||
"sha256": "ac81e975c299da7d50cfda7fc0fee33c356bd31a4e17a7f0f8e49905e205051a"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 167362,
|
||||
"gw_pid": 167375,
|
||||
"cgroup": null,
|
||||
"load_avg_at_start": [
|
||||
0.4,
|
||||
0.96,
|
||||
1.44
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 27,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 57124,
|
||||
"pss_kb": 31720,
|
||||
"private_dirty_kb": 20020,
|
||||
"vmhwm_kb": 57124,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 1
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1031,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 6665,
|
||||
"pty_writes": 9,
|
||||
"rss_kb": 110124,
|
||||
"pss_kb": 72684,
|
||||
"private_dirty_kb": 51672,
|
||||
"vmhwm_kb": 110124,
|
||||
"utime_ticks": 26,
|
||||
"stime_ticks": 4
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1481,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 10675,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 128172,
|
||||
"pss_kb": 90565,
|
||||
"private_dirty_kb": 68808,
|
||||
"vmhwm_kb": 128256,
|
||||
"utime_ticks": 34,
|
||||
"stime_ticks": 5
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1557,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 18489,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 166540,
|
||||
"pss_kb": 128783,
|
||||
"private_dirty_kb": 106984,
|
||||
"vmhwm_kb": 166772,
|
||||
"utime_ticks": 44,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1582,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 22560,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 182916,
|
||||
"pss_kb": 145159,
|
||||
"private_dirty_kb": 123360,
|
||||
"vmhwm_kb": 182992,
|
||||
"utime_ticks": 50,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 1583,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 22560,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 183032,
|
||||
"pss_kb": 145275,
|
||||
"private_dirty_kb": 123476,
|
||||
"vmhwm_kb": 183036,
|
||||
"utime_ticks": 51,
|
||||
"stime_ticks": 6
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2035,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34064,
|
||||
"pty_writes": 19,
|
||||
"rss_kb": 187616,
|
||||
"pss_kb": 149816,
|
||||
"private_dirty_kb": 127996,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 64,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3044,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34154,
|
||||
"pty_writes": 21,
|
||||
"rss_kb": 187632,
|
||||
"pss_kb": 149832,
|
||||
"private_dirty_kb": 128012,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4047,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34244,
|
||||
"pty_writes": 23,
|
||||
"rss_kb": 187636,
|
||||
"pss_kb": 149878,
|
||||
"private_dirty_kb": 128016,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5054,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34334,
|
||||
"pty_writes": 25,
|
||||
"rss_kb": 187644,
|
||||
"pss_kb": 150010,
|
||||
"private_dirty_kb": 128024,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6059,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34424,
|
||||
"pty_writes": 27,
|
||||
"rss_kb": 187652,
|
||||
"pss_kb": 150018,
|
||||
"private_dirty_kb": 128032,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7064,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34514,
|
||||
"pty_writes": 29,
|
||||
"rss_kb": 187652,
|
||||
"pss_kb": 150018,
|
||||
"private_dirty_kb": 128032,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 65,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 8068,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34604,
|
||||
"pty_writes": 31,
|
||||
"rss_kb": 187656,
|
||||
"pss_kb": 150022,
|
||||
"private_dirty_kb": 128036,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 9073,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34694,
|
||||
"pty_writes": 33,
|
||||
"rss_kb": 187656,
|
||||
"pss_kb": 150022,
|
||||
"private_dirty_kb": 128036,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 10087,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34784,
|
||||
"pty_writes": 35,
|
||||
"rss_kb": 187656,
|
||||
"pss_kb": 150022,
|
||||
"private_dirty_kb": 128036,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 11096,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 34904,
|
||||
"pty_writes": 37,
|
||||
"rss_kb": 187664,
|
||||
"pss_kb": 148140,
|
||||
"private_dirty_kb": 128044,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 12098,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35013,
|
||||
"pty_writes": 39,
|
||||
"rss_kb": 187664,
|
||||
"pss_kb": 145076,
|
||||
"private_dirty_kb": 128044,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 13098,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35103,
|
||||
"pty_writes": 41,
|
||||
"rss_kb": 187664,
|
||||
"pss_kb": 145045,
|
||||
"private_dirty_kb": 128044,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 66,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 14102,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35193,
|
||||
"pty_writes": 43,
|
||||
"rss_kb": 187664,
|
||||
"pss_kb": 145044,
|
||||
"private_dirty_kb": 128044,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 15111,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35283,
|
||||
"pty_writes": 45,
|
||||
"rss_kb": 187664,
|
||||
"pss_kb": 145044,
|
||||
"private_dirty_kb": 128044,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 16118,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35373,
|
||||
"pty_writes": 47,
|
||||
"rss_kb": 187680,
|
||||
"pss_kb": 145060,
|
||||
"private_dirty_kb": 128060,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 16674,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 35463,
|
||||
"pty_writes": 49,
|
||||
"rss_kb": 187680,
|
||||
"pss_kb": 145060,
|
||||
"private_dirty_kb": 128060,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 17125,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 46138,
|
||||
"pty_writes": 56,
|
||||
"rss_kb": 175904,
|
||||
"pss_kb": 133284,
|
||||
"private_dirty_kb": 116284,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 71,
|
||||
"stime_ticks": 7
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 18129,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 49784,
|
||||
"pty_writes": 59,
|
||||
"rss_kb": 177964,
|
||||
"pss_kb": 135344,
|
||||
"private_dirty_kb": 118344,
|
||||
"vmhwm_kb": 196580,
|
||||
"utime_ticks": 72,
|
||||
"stime_ticks": 7
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 226
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "commands.catalog",
|
||||
"t_ms": 226
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "setup.status",
|
||||
"t_ms": 251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 1756
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 3243
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 4751
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 5253
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 6258
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 7766
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 9248
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 10263
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 10767
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 12272
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 13749
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 15261
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 15261
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 16771
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 16796
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "terminal.resize",
|
||||
"t_ms": 17197
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 18255
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 18284
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 300,
|
||||
"events_streamed": 1051,
|
||||
"pty_bytes_total": 50236,
|
||||
"pty_data_callbacks": 64,
|
||||
"first_byte_ms": 110,
|
||||
"session_create_ms": 251,
|
||||
"stream_start_ms": 1455,
|
||||
"vmhwm_kb": 196580,
|
||||
"cg_peak": null,
|
||||
"drain_max_loop_lag_ms": 3,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": "0f62155086e89590f62e059cc7bcf0851b6c88dac942a8f2303ac905481dea48"
|
||||
},
|
||||
"digest_text": "Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit┃exercitationincididuntdolorproidentvelitlaborismagnaamet.─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯│┃Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit.│Amet culpa cillum commodo enim adipiscing deserunt nulla duis veniam sed.│Quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna.│Esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute quis.│Anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip.│Magna amet culpa cillum.│Aute quis eiusmod lorem occaecat.│ └─ ● Terminal(\"Proident velit laboris magna.\") (0.3s)│ └─ Args:│Proident velit laboris magna amet culpa cillum commodo enim adipiscing deserunt nulla.│Elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident.│Ullamco labore sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit.│Nulla duis veniam sed.│Dolor proident velit laboris magna.│Result:│Pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris.│Sit sunt esse aliquip aliqua consectetur officia fugiat consequat minim elit mollit pariatur aute.││┊ Minimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitationincididuntdolor.Officia│fugiatconsequatminimelitmollitpariaturautequiseiusmodloremoccaecatreprehenderitexercitation.│┊ Temporipsumcupidatatvoluptateullamcolaboresitsuntessealiquipaliqua.Excepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresitsuntesse.Veniamsedanimexcepteurirurenostrudtempor│ipsumcupidatatvoluptateullamcolaboresit.││• Suntessealiquipaliquaconsectetur.│• Consequatminimelitmollitpariaturautequis.│• Eiusmodloremoccaecatreprehenderit.││─ ts│constx4=58│functionf3(){│returnx│}││Exercitationincididuntdolorproidentvelitlaborismagnaametculpacillum.Loremoccaecatreprehenderit│exercitationincididuntdolorproidentvelitlaborismagnaamet.┃─ ready │ fake model │ 16s │ ✓ 15s │ voice off ─ …es-agent (…i-native-engine)❯768"
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "gate",
|
||||
"ui": "opentui",
|
||||
"config": "otui-capped",
|
||||
"mode": "digest",
|
||||
"rep": 0,
|
||||
"run_id": "mqaf8cjn-3smp",
|
||||
"utc": "2026-06-12T04:23:16.355Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": null,
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": 3000,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-300.ndjson",
|
||||
"msgs": 300,
|
||||
"sha256": "ac81e975c299da7d50cfda7fc0fee33c356bd31a4e17a7f0f8e49905e205051a"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 168251,
|
||||
"gw_pid": 168266,
|
||||
"cgroup": null,
|
||||
"load_avg_at_start": [
|
||||
0.31,
|
||||
0.92,
|
||||
1.42
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 25,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 54688,
|
||||
"pss_kb": 25883,
|
||||
"private_dirty_kb": 17496,
|
||||
"vmhwm_kb": 54768,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1030,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 28909,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 104648,
|
||||
"pss_kb": 61159,
|
||||
"private_dirty_kb": 48340,
|
||||
"vmhwm_kb": 107112,
|
||||
"utime_ticks": 19,
|
||||
"stime_ticks": 2
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1382,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 111376,
|
||||
"pss_kb": 67773,
|
||||
"private_dirty_kb": 54944,
|
||||
"vmhwm_kb": 111396,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1383,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 111648,
|
||||
"pss_kb": 68045,
|
||||
"private_dirty_kb": 55216,
|
||||
"vmhwm_kb": 111768,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1383,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 111880,
|
||||
"pss_kb": 68277,
|
||||
"private_dirty_kb": 55448,
|
||||
"vmhwm_kb": 111748,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 1384,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 111748,
|
||||
"pss_kb": 68145,
|
||||
"private_dirty_kb": 55316,
|
||||
"vmhwm_kb": 111752,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2036,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35558,
|
||||
"pty_writes": 17,
|
||||
"rss_kb": 300388,
|
||||
"pss_kb": 254649,
|
||||
"private_dirty_kb": 240344,
|
||||
"vmhwm_kb": 301568,
|
||||
"utime_ticks": 109,
|
||||
"stime_ticks": 11
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 2867,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 35630,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 300420,
|
||||
"pss_kb": 254681,
|
||||
"private_dirty_kb": 240376,
|
||||
"vmhwm_kb": 301568,
|
||||
"utime_ticks": 109,
|
||||
"stime_ticks": 11
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3045,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 46541,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 300480,
|
||||
"pss_kb": 254741,
|
||||
"private_dirty_kb": 240436,
|
||||
"vmhwm_kb": 301568,
|
||||
"utime_ticks": 111,
|
||||
"stime_ticks": 11
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4050,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 57863,
|
||||
"pty_writes": 27,
|
||||
"rss_kb": 300528,
|
||||
"pss_kb": 254789,
|
||||
"private_dirty_kb": 240484,
|
||||
"vmhwm_kb": 301568,
|
||||
"utime_ticks": 112,
|
||||
"stime_ticks": 11
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 175
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "startup.catalog",
|
||||
"t_ms": 175
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "model.options",
|
||||
"t_ms": 175
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 4721
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 300,
|
||||
"events_streamed": 1051,
|
||||
"pty_bytes_total": 62674,
|
||||
"pty_data_callbacks": 32,
|
||||
"first_byte_ms": 130,
|
||||
"session_create_ms": 175,
|
||||
"stream_start_ms": 1380,
|
||||
"vmhwm_kb": 301568,
|
||||
"cg_peak": null,
|
||||
"drain_max_loop_lag_ms": 3,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": "4c4f97e930ebbaa2f174eaf5410c4d100689c671220623ad906530d885eef948"
|
||||
},
|
||||
"digest_text": "⚕ Hermes Agent · opentui · ready ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── $ terminal Culpa cillum commodo enim. · 3.7s (2 lines) ◇ read_file Duis veniam sed anim. · 3.8s (18 lines) ◦ edit_file Tempor ipsum cupidatat voluptate. · 3.9s (7 lines) ◦ grep Sunt esse aliquip aliqua. · 4.0s (2 lines) ● web_search Consequat minim elit mollit. · 0.1s (18 lines) ◆ write_file Eiusmod lorem occaecat reprehenderit. · 0.2s (7 lines) $ terminal Proident velit laboris magna. · 0.3s (2 lines) Minim elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor. Officia fugiat consequat minim elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation. ⧉ copy ⚕ Tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip aliqua. Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse. Veniam sed anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit. - Sunt esse aliquip aliqua consectetur. - Consequat minim elit mollit pariatur aute quis. - Eiusmod lorem occaecat reprehenderit. const x4 = 58 function f3() { return x } Exercitation incididunt dolor proident velit laboris magna amet culpa cillum. Lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna amet. ⧉ copy ▄ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ● fake-model │ up: Ns │ …/quiet-quill/hermes-agent ❯ Type your message"
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "gate",
|
||||
"ui": "opentui",
|
||||
"config": "otui-capped",
|
||||
"mode": "digest",
|
||||
"rep": 1,
|
||||
"run_id": "mqaf8nws-3ryc",
|
||||
"utc": "2026-06-12T04:23:31.084Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": null,
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": 3000,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-300.ndjson",
|
||||
"msgs": 300,
|
||||
"sha256": "ac81e975c299da7d50cfda7fc0fee33c356bd31a4e17a7f0f8e49905e205051a"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 168675,
|
||||
"gw_pid": 168684,
|
||||
"cgroup": null,
|
||||
"load_avg_at_start": [
|
||||
0.51,
|
||||
0.93,
|
||||
1.42
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 26,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 54724,
|
||||
"pss_kb": 25927,
|
||||
"private_dirty_kb": 17484,
|
||||
"vmhwm_kb": 54756,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1033,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 28909,
|
||||
"pty_writes": 13,
|
||||
"rss_kb": 104792,
|
||||
"pss_kb": 61265,
|
||||
"private_dirty_kb": 48340,
|
||||
"vmhwm_kb": 107580,
|
||||
"utime_ticks": 17,
|
||||
"stime_ticks": 2
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1386,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 112180,
|
||||
"pss_kb": 68538,
|
||||
"private_dirty_kb": 55604,
|
||||
"vmhwm_kb": 112212,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1387,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 112424,
|
||||
"pss_kb": 68782,
|
||||
"private_dirty_kb": 55848,
|
||||
"vmhwm_kb": 112444,
|
||||
"utime_ticks": 23,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1388,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 112448,
|
||||
"pss_kb": 68806,
|
||||
"private_dirty_kb": 55872,
|
||||
"vmhwm_kb": 112448,
|
||||
"utime_ticks": 23,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 1388,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 112448,
|
||||
"pss_kb": 68806,
|
||||
"private_dirty_kb": 55872,
|
||||
"vmhwm_kb": 112448,
|
||||
"utime_ticks": 23,
|
||||
"stime_ticks": 3
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2041,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 35558,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 274976,
|
||||
"pss_kb": 229157,
|
||||
"private_dirty_kb": 214852,
|
||||
"vmhwm_kb": 324708,
|
||||
"utime_ticks": 106,
|
||||
"stime_ticks": 11
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 2861,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 35630,
|
||||
"pty_writes": 19,
|
||||
"rss_kb": 275008,
|
||||
"pss_kb": 229189,
|
||||
"private_dirty_kb": 214884,
|
||||
"vmhwm_kb": 324708,
|
||||
"utime_ticks": 107,
|
||||
"stime_ticks": 11
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3049,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 46541,
|
||||
"pty_writes": 23,
|
||||
"rss_kb": 275068,
|
||||
"pss_kb": 229249,
|
||||
"private_dirty_kb": 214944,
|
||||
"vmhwm_kb": 324708,
|
||||
"utime_ticks": 108,
|
||||
"stime_ticks": 11
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4055,
|
||||
"msgs": 300,
|
||||
"events": null,
|
||||
"pty_bytes": 57863,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 275112,
|
||||
"pss_kb": 229288,
|
||||
"private_dirty_kb": 214988,
|
||||
"vmhwm_kb": 324708,
|
||||
"utime_ticks": 109,
|
||||
"stime_ticks": 11
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 176
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "startup.catalog",
|
||||
"t_ms": 176
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "model.options",
|
||||
"t_ms": 176
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 4707
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 300,
|
||||
"events_streamed": 1051,
|
||||
"pty_bytes_total": 62674,
|
||||
"pty_data_callbacks": 33,
|
||||
"first_byte_ms": 128,
|
||||
"session_create_ms": 176,
|
||||
"stream_start_ms": 1385,
|
||||
"vmhwm_kb": 324708,
|
||||
"cg_peak": null,
|
||||
"drain_max_loop_lag_ms": 4,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": "4c4f97e930ebbaa2f174eaf5410c4d100689c671220623ad906530d885eef948"
|
||||
},
|
||||
"digest_text": "⚕ Hermes Agent · opentui · ready ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── $ terminal Culpa cillum commodo enim. · 3.7s (2 lines) ◇ read_file Duis veniam sed anim. · 3.8s (18 lines) ◦ edit_file Tempor ipsum cupidatat voluptate. · 3.9s (7 lines) ◦ grep Sunt esse aliquip aliqua. · 4.0s (2 lines) ● web_search Consequat minim elit mollit. · 0.1s (18 lines) ◆ write_file Eiusmod lorem occaecat reprehenderit. · 0.2s (7 lines) $ terminal Proident velit laboris magna. · 0.3s (2 lines) Minim elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation incididunt dolor. Officia fugiat consequat minim elit mollit pariatur aute quis eiusmod lorem occaecat reprehenderit exercitation. ⧉ copy ⚕ Tempor ipsum cupidatat voluptate ullamco labore sit sunt esse aliquip aliqua. Excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit sunt esse. Veniam sed anim excepteur irure nostrud tempor ipsum cupidatat voluptate ullamco labore sit. - Sunt esse aliquip aliqua consectetur. - Consequat minim elit mollit pariatur aute quis. - Eiusmod lorem occaecat reprehenderit. const x4 = 58 function f3() { return x } Exercitation incididunt dolor proident velit laboris magna amet culpa cillum. Lorem occaecat reprehenderit exercitation incididunt dolor proident velit laboris magna amet. ⧉ copy ▄ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ● fake-model │ up: Ns │ …/quiet-quill/hermes-agent ❯ Type your message"
|
||||
}
|
||||
854
bench/results/2026-06-12T0424-f0ec24a-mem2000-ink-ink-r0.json
Normal file
854
bench/results/2026-06-12T0424-f0ec24a-mem2000-ink-ink-r0.json
Normal file
|
|
@ -0,0 +1,854 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "mem2000",
|
||||
"ui": "ink",
|
||||
"config": "ink",
|
||||
"mode": "mem",
|
||||
"rep": 0,
|
||||
"run_id": "mqafa3wx-7qr8",
|
||||
"utc": "2026-06-12T04:24:38.481Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": "2G",
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": null,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-2000.ndjson",
|
||||
"msgs": 2000,
|
||||
"sha256": "645b9ee4fdaccee45172fcec8af4a0b01a5f9aeca56ce45d8e84c4276472f99c"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 170578,
|
||||
"gw_pid": 170601,
|
||||
"cgroup": "/sys/fs/cgroup/user.slice/user-1001.slice/session-7349.scope",
|
||||
"load_avg_at_start": [
|
||||
0.45,
|
||||
0.83,
|
||||
1.34
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 26,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 29152,
|
||||
"pss_kb": 10292,
|
||||
"private_dirty_kb": 4420,
|
||||
"vmhwm_kb": 29152,
|
||||
"utime_ticks": 0,
|
||||
"stime_ticks": 0,
|
||||
"cg_current": 5940740096,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1031,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 6190,
|
||||
"pty_writes": 13,
|
||||
"rss_kb": 111012,
|
||||
"pss_kb": 67797,
|
||||
"private_dirty_kb": 52260,
|
||||
"vmhwm_kb": 111012,
|
||||
"utime_ticks": 24,
|
||||
"stime_ticks": 4,
|
||||
"cg_current": 5941399552,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1760,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 6411,
|
||||
"pty_writes": 16,
|
||||
"rss_kb": 114928,
|
||||
"pss_kb": 71604,
|
||||
"private_dirty_kb": 55388,
|
||||
"vmhwm_kb": 114936,
|
||||
"utime_ticks": 26,
|
||||
"stime_ticks": 4,
|
||||
"cg_current": 5940625408,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1835,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 13769,
|
||||
"pty_writes": 20,
|
||||
"rss_kb": 140880,
|
||||
"pss_kb": 97258,
|
||||
"private_dirty_kb": 80960,
|
||||
"vmhwm_kb": 140888,
|
||||
"utime_ticks": 39,
|
||||
"stime_ticks": 5,
|
||||
"cg_current": 5940695040,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1860,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 17619,
|
||||
"pty_writes": 21,
|
||||
"rss_kb": 153592,
|
||||
"pss_kb": 109970,
|
||||
"private_dirty_kb": 93672,
|
||||
"vmhwm_kb": 153620,
|
||||
"utime_ticks": 44,
|
||||
"stime_ticks": 6,
|
||||
"cg_current": 5940695040,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1937,
|
||||
"msgs": 400,
|
||||
"events": 1432,
|
||||
"pty_bytes": 26009,
|
||||
"pty_writes": 25,
|
||||
"rss_kb": 172120,
|
||||
"pss_kb": 128498,
|
||||
"private_dirty_kb": 112200,
|
||||
"vmhwm_kb": 178392,
|
||||
"utime_ticks": 59,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5940998144,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1963,
|
||||
"msgs": 501,
|
||||
"events": 1792,
|
||||
"pty_bytes": 32671,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 173420,
|
||||
"pss_kb": 129798,
|
||||
"private_dirty_kb": 113500,
|
||||
"vmhwm_kb": 178392,
|
||||
"utime_ticks": 62,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5940809728,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2011,
|
||||
"msgs": 601,
|
||||
"events": 2154,
|
||||
"pty_bytes": 43052,
|
||||
"pty_writes": 31,
|
||||
"rss_kb": 179416,
|
||||
"pss_kb": 135784,
|
||||
"private_dirty_kb": 119496,
|
||||
"vmhwm_kb": 179440,
|
||||
"utime_ticks": 71,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2036,
|
||||
"msgs": 701,
|
||||
"events": 2496,
|
||||
"pty_bytes": 46699,
|
||||
"pty_writes": 32,
|
||||
"rss_kb": 182248,
|
||||
"pss_kb": 138616,
|
||||
"private_dirty_kb": 122328,
|
||||
"vmhwm_kb": 182248,
|
||||
"utime_ticks": 74,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2038,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 46699,
|
||||
"pty_writes": 32,
|
||||
"rss_kb": 182284,
|
||||
"pss_kb": 138652,
|
||||
"private_dirty_kb": 122364,
|
||||
"vmhwm_kb": 182320,
|
||||
"utime_ticks": 75,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2061,
|
||||
"msgs": 801,
|
||||
"events": 2857,
|
||||
"pty_bytes": 50621,
|
||||
"pty_writes": 33,
|
||||
"rss_kb": 184112,
|
||||
"pss_kb": 140480,
|
||||
"private_dirty_kb": 124192,
|
||||
"vmhwm_kb": 184116,
|
||||
"utime_ticks": 77,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2112,
|
||||
"msgs": 901,
|
||||
"events": 3245,
|
||||
"pty_bytes": 58620,
|
||||
"pty_writes": 35,
|
||||
"rss_kb": 193376,
|
||||
"pss_kb": 149741,
|
||||
"private_dirty_kb": 133456,
|
||||
"vmhwm_kb": 193384,
|
||||
"utime_ticks": 85,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5940846592,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2163,
|
||||
"msgs": 1001,
|
||||
"events": 3588,
|
||||
"pty_bytes": 65835,
|
||||
"pty_writes": 37,
|
||||
"rss_kb": 197156,
|
||||
"pss_kb": 153521,
|
||||
"private_dirty_kb": 137236,
|
||||
"vmhwm_kb": 197164,
|
||||
"utime_ticks": 91,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5940846592,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2188,
|
||||
"msgs": 1101,
|
||||
"events": 3928,
|
||||
"pty_bytes": 73273,
|
||||
"pty_writes": 39,
|
||||
"rss_kb": 200276,
|
||||
"pss_kb": 156641,
|
||||
"private_dirty_kb": 140356,
|
||||
"vmhwm_kb": 200276,
|
||||
"utime_ticks": 95,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2213,
|
||||
"msgs": 1201,
|
||||
"events": 4298,
|
||||
"pty_bytes": 77046,
|
||||
"pty_writes": 40,
|
||||
"rss_kb": 203176,
|
||||
"pss_kb": 159541,
|
||||
"private_dirty_kb": 143256,
|
||||
"vmhwm_kb": 203180,
|
||||
"utime_ticks": 99,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2262,
|
||||
"msgs": 1300,
|
||||
"events": 4659,
|
||||
"pty_bytes": 88185,
|
||||
"pty_writes": 43,
|
||||
"rss_kb": 210112,
|
||||
"pss_kb": 166477,
|
||||
"private_dirty_kb": 150192,
|
||||
"vmhwm_kb": 210124,
|
||||
"utime_ticks": 107,
|
||||
"stime_ticks": 9,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2263,
|
||||
"msgs": 1400,
|
||||
"events": 5011,
|
||||
"pty_bytes": 88185,
|
||||
"pty_writes": 43,
|
||||
"rss_kb": 210136,
|
||||
"pss_kb": 166501,
|
||||
"private_dirty_kb": 150216,
|
||||
"vmhwm_kb": 210136,
|
||||
"utime_ticks": 107,
|
||||
"stime_ticks": 9,
|
||||
"cg_current": 5940842496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2438,
|
||||
"msgs": 1500,
|
||||
"events": 5384,
|
||||
"pty_bytes": 95749,
|
||||
"pty_writes": 45,
|
||||
"rss_kb": 218668,
|
||||
"pss_kb": 175033,
|
||||
"private_dirty_kb": 158748,
|
||||
"vmhwm_kb": 218672,
|
||||
"utime_ticks": 127,
|
||||
"stime_ticks": 9,
|
||||
"cg_current": 5940731904,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2587,
|
||||
"msgs": 1600,
|
||||
"events": 5730,
|
||||
"pty_bytes": 103499,
|
||||
"pty_writes": 48,
|
||||
"rss_kb": 225504,
|
||||
"pss_kb": 181869,
|
||||
"private_dirty_kb": 165584,
|
||||
"vmhwm_kb": 225644,
|
||||
"utime_ticks": 144,
|
||||
"stime_ticks": 9,
|
||||
"cg_current": 5940396032,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2639,
|
||||
"msgs": 1700,
|
||||
"events": 6100,
|
||||
"pty_bytes": 111074,
|
||||
"pty_writes": 51,
|
||||
"rss_kb": 232268,
|
||||
"pss_kb": 188633,
|
||||
"private_dirty_kb": 172348,
|
||||
"vmhwm_kb": 232276,
|
||||
"utime_ticks": 151,
|
||||
"stime_ticks": 9,
|
||||
"cg_current": 5940883456,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2665,
|
||||
"msgs": 1800,
|
||||
"events": 6455,
|
||||
"pty_bytes": 114381,
|
||||
"pty_writes": 54,
|
||||
"rss_kb": 235400,
|
||||
"pss_kb": 191765,
|
||||
"private_dirty_kb": 175480,
|
||||
"vmhwm_kb": 235400,
|
||||
"utime_ticks": 155,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5940625408,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2715,
|
||||
"msgs": 1900,
|
||||
"events": 6838,
|
||||
"pty_bytes": 117335,
|
||||
"pty_writes": 55,
|
||||
"rss_kb": 246420,
|
||||
"pss_kb": 202785,
|
||||
"private_dirty_kb": 186500,
|
||||
"vmhwm_kb": 246440,
|
||||
"utime_ticks": 163,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5940895744,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2738,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 124683,
|
||||
"pty_writes": 57,
|
||||
"rss_kb": 244808,
|
||||
"pss_kb": 201173,
|
||||
"private_dirty_kb": 184888,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 167,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5941153792,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 2740,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 124683,
|
||||
"pty_writes": 57,
|
||||
"rss_kb": 244808,
|
||||
"pss_kb": 201173,
|
||||
"private_dirty_kb": 184888,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 167,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5941153792,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3040,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132349,
|
||||
"pty_writes": 60,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 172,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5941141504,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4048,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132439,
|
||||
"pty_writes": 62,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 172,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5942734848,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5048,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132529,
|
||||
"pty_writes": 64,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 172,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5952634880,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6052,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132619,
|
||||
"pty_writes": 66,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 172,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5955338240,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7060,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132709,
|
||||
"pty_writes": 68,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 172,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5956476928,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 8072,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132799,
|
||||
"pty_writes": 70,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 173,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5959532544,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 9078,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132889,
|
||||
"pty_writes": 72,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 173,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5958893568,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 10091,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 132979,
|
||||
"pty_writes": 74,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 173,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5964316672,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 11107,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133099,
|
||||
"pty_writes": 76,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 173,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5973635072,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 12113,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133189,
|
||||
"pty_writes": 78,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 173,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5948555264,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 13120,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133298,
|
||||
"pty_writes": 80,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 174,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5949779968,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 14133,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133388,
|
||||
"pty_writes": 82,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 174,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5949759488,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 15144,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133478,
|
||||
"pty_writes": 84,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 174,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5955108864,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 16156,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133568,
|
||||
"pty_writes": 86,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 174,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5958033408,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 17164,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 133658,
|
||||
"pty_writes": 88,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 174,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5961461760,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 17788,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 133748,
|
||||
"pty_writes": 90,
|
||||
"rss_kb": 246068,
|
||||
"pss_kb": 202433,
|
||||
"private_dirty_kb": 186148,
|
||||
"vmhwm_kb": 249288,
|
||||
"utime_ticks": 175,
|
||||
"stime_ticks": 10,
|
||||
"cg_current": 5962797056,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "commands.catalog",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "setup.status",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 252
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 1758
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 3265
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 4746
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 5247
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 6251
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 7763
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 9254
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 10265
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 10746
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 12262
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 13753
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "config.get",
|
||||
"t_ms": 15242
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 15268
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.active_list",
|
||||
"t_ms": 16760
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 17801
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 2000,
|
||||
"events_streamed": 7151,
|
||||
"pty_bytes_total": 134155,
|
||||
"pty_data_callbacks": 98,
|
||||
"first_byte_ms": 114,
|
||||
"session_create_ms": 252,
|
||||
"stream_start_ms": 1758,
|
||||
"vmhwm_kb": 249288,
|
||||
"cg_peak": 7893282816,
|
||||
"drain_max_loop_lag_ms": 5,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": null
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,611 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "mem2000",
|
||||
"ui": "opentui",
|
||||
"config": "otui-capped",
|
||||
"mode": "mem",
|
||||
"rep": 0,
|
||||
"run_id": "mqaf9blb-m7l3",
|
||||
"utc": "2026-06-12T04:24:01.775Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": "2G",
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": 3000,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-2000.ndjson",
|
||||
"msgs": 2000,
|
||||
"sha256": "645b9ee4fdaccee45172fcec8af4a0b01a5f9aeca56ce45d8e84c4276472f99c"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 169517,
|
||||
"gw_pid": 169526,
|
||||
"cgroup": "/sys/fs/cgroup/user.slice/user-1001.slice/session-7349.scope",
|
||||
"load_avg_at_start": [
|
||||
0.73,
|
||||
0.93,
|
||||
1.39
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 28,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 31864,
|
||||
"pss_kb": 12337,
|
||||
"private_dirty_kb": 6144,
|
||||
"vmhwm_kb": 31744,
|
||||
"utime_ticks": 1,
|
||||
"stime_ticks": 0,
|
||||
"cg_current": 6002446336,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1037,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 28909,
|
||||
"pty_writes": 10,
|
||||
"rss_kb": 104788,
|
||||
"pss_kb": 60315,
|
||||
"private_dirty_kb": 48340,
|
||||
"vmhwm_kb": 107352,
|
||||
"utime_ticks": 18,
|
||||
"stime_ticks": 1,
|
||||
"cg_current": 5998682112,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1695,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 112868,
|
||||
"pss_kb": 68274,
|
||||
"private_dirty_kb": 56296,
|
||||
"vmhwm_kb": 113072,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 1,
|
||||
"cg_current": 5998612480,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1696,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 113124,
|
||||
"pss_kb": 68530,
|
||||
"private_dirty_kb": 56552,
|
||||
"vmhwm_kb": 112992,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 1,
|
||||
"cg_current": 5998616576,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1697,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 113120,
|
||||
"pss_kb": 68526,
|
||||
"private_dirty_kb": 56548,
|
||||
"vmhwm_kb": 113188,
|
||||
"utime_ticks": 22,
|
||||
"stime_ticks": 1,
|
||||
"cg_current": 5998616576,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2046,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 227468,
|
||||
"pss_kb": 180839,
|
||||
"private_dirty_kb": 167776,
|
||||
"vmhwm_kb": 227468,
|
||||
"utime_ticks": 77,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5999181824,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2097,
|
||||
"msgs": 400,
|
||||
"events": 1432,
|
||||
"pty_bytes": 32463,
|
||||
"pty_writes": 13,
|
||||
"rss_kb": 229936,
|
||||
"pss_kb": 183307,
|
||||
"private_dirty_kb": 170244,
|
||||
"vmhwm_kb": 229936,
|
||||
"utime_ticks": 82,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5998927872,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2148,
|
||||
"msgs": 501,
|
||||
"events": 1792,
|
||||
"pty_bytes": 36002,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 231552,
|
||||
"pss_kb": 184810,
|
||||
"private_dirty_kb": 171680,
|
||||
"vmhwm_kb": 231560,
|
||||
"utime_ticks": 88,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5998673920,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2325,
|
||||
"msgs": 601,
|
||||
"events": 2154,
|
||||
"pty_bytes": 38789,
|
||||
"pty_writes": 16,
|
||||
"rss_kb": 268004,
|
||||
"pss_kb": 221200,
|
||||
"private_dirty_kb": 208008,
|
||||
"vmhwm_kb": 268056,
|
||||
"utime_ticks": 117,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5998878720,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2573,
|
||||
"msgs": 701,
|
||||
"events": 2496,
|
||||
"pty_bytes": 41517,
|
||||
"pty_writes": 18,
|
||||
"rss_kb": 307192,
|
||||
"pss_kb": 260272,
|
||||
"private_dirty_kb": 247072,
|
||||
"vmhwm_kb": 342248,
|
||||
"utime_ticks": 165,
|
||||
"stime_ticks": 11,
|
||||
"cg_current": 5998968832,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2805,
|
||||
"msgs": 801,
|
||||
"events": 2857,
|
||||
"pty_bytes": 42840,
|
||||
"pty_writes": 19,
|
||||
"rss_kb": 337800,
|
||||
"pss_kb": 290880,
|
||||
"private_dirty_kb": 277680,
|
||||
"vmhwm_kb": 342248,
|
||||
"utime_ticks": 192,
|
||||
"stime_ticks": 12,
|
||||
"cg_current": 5998862336,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3050,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 44316,
|
||||
"pty_writes": 20,
|
||||
"rss_kb": 366384,
|
||||
"pss_kb": 319464,
|
||||
"private_dirty_kb": 306264,
|
||||
"vmhwm_kb": 366472,
|
||||
"utime_ticks": 219,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5998555136,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3102,
|
||||
"msgs": 901,
|
||||
"events": 3245,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 368804,
|
||||
"pss_kb": 321880,
|
||||
"private_dirty_kb": 308684,
|
||||
"vmhwm_kb": 368840,
|
||||
"utime_ticks": 225,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5998551040,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3104,
|
||||
"msgs": 1001,
|
||||
"events": 3588,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 368896,
|
||||
"pss_kb": 321972,
|
||||
"private_dirty_kb": 308776,
|
||||
"vmhwm_kb": 368916,
|
||||
"utime_ticks": 226,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5998551040,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3106,
|
||||
"msgs": 1101,
|
||||
"events": 3928,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 368928,
|
||||
"pss_kb": 322004,
|
||||
"private_dirty_kb": 308808,
|
||||
"vmhwm_kb": 368948,
|
||||
"utime_ticks": 226,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5998551040,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3107,
|
||||
"msgs": 1201,
|
||||
"events": 4298,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 368968,
|
||||
"pss_kb": 322044,
|
||||
"private_dirty_kb": 308848,
|
||||
"vmhwm_kb": 368988,
|
||||
"utime_ticks": 226,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5998551040,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3125,
|
||||
"msgs": 1300,
|
||||
"events": 4659,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 371680,
|
||||
"pss_kb": 324756,
|
||||
"private_dirty_kb": 311560,
|
||||
"vmhwm_kb": 371776,
|
||||
"utime_ticks": 228,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5999067136,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3127,
|
||||
"msgs": 1400,
|
||||
"events": 5011,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 371916,
|
||||
"pss_kb": 324992,
|
||||
"private_dirty_kb": 311796,
|
||||
"vmhwm_kb": 372020,
|
||||
"utime_ticks": 228,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5999067136,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3128,
|
||||
"msgs": 1500,
|
||||
"events": 5384,
|
||||
"pty_bytes": 47642,
|
||||
"pty_writes": 22,
|
||||
"rss_kb": 372140,
|
||||
"pss_kb": 325216,
|
||||
"private_dirty_kb": 312020,
|
||||
"vmhwm_kb": 372188,
|
||||
"utime_ticks": 228,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5999067136,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 4032,
|
||||
"msgs": 1600,
|
||||
"events": 5730,
|
||||
"pty_bytes": 50803,
|
||||
"pty_writes": 24,
|
||||
"rss_kb": 535276,
|
||||
"pss_kb": 488352,
|
||||
"private_dirty_kb": 475156,
|
||||
"vmhwm_kb": 535284,
|
||||
"utime_ticks": 350,
|
||||
"stime_ticks": 20,
|
||||
"cg_current": 5998948352,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4059,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 50803,
|
||||
"pty_writes": 24,
|
||||
"rss_kb": 540160,
|
||||
"pss_kb": 493236,
|
||||
"private_dirty_kb": 480040,
|
||||
"vmhwm_kb": 540220,
|
||||
"utime_ticks": 353,
|
||||
"stime_ticks": 21,
|
||||
"cg_current": 5998952448,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 4612,
|
||||
"msgs": 1700,
|
||||
"events": 6100,
|
||||
"pty_bytes": 54799,
|
||||
"pty_writes": 26,
|
||||
"rss_kb": 564292,
|
||||
"pss_kb": 517368,
|
||||
"private_dirty_kb": 504172,
|
||||
"vmhwm_kb": 564368,
|
||||
"utime_ticks": 410,
|
||||
"stime_ticks": 22,
|
||||
"cg_current": 5999460352,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 5011,
|
||||
"msgs": 1800,
|
||||
"events": 6455,
|
||||
"pty_bytes": 56349,
|
||||
"pty_writes": 27,
|
||||
"rss_kb": 591676,
|
||||
"pss_kb": 544752,
|
||||
"private_dirty_kb": 531556,
|
||||
"vmhwm_kb": 591676,
|
||||
"utime_ticks": 453,
|
||||
"stime_ticks": 24,
|
||||
"cg_current": 5982150656,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5061,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 56349,
|
||||
"pty_writes": 27,
|
||||
"rss_kb": 591676,
|
||||
"pss_kb": 544752,
|
||||
"private_dirty_kb": 531556,
|
||||
"vmhwm_kb": 591676,
|
||||
"utime_ticks": 458,
|
||||
"stime_ticks": 24,
|
||||
"cg_current": 5982121984,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 5638,
|
||||
"msgs": 1900,
|
||||
"events": 6838,
|
||||
"pty_bytes": 60037,
|
||||
"pty_writes": 29,
|
||||
"rss_kb": 621532,
|
||||
"pss_kb": 574608,
|
||||
"private_dirty_kb": 561412,
|
||||
"vmhwm_kb": 621532,
|
||||
"utime_ticks": 518,
|
||||
"stime_ticks": 25,
|
||||
"cg_current": 5983272960,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6066,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 61205,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 654116,
|
||||
"pss_kb": 607192,
|
||||
"private_dirty_kb": 593996,
|
||||
"vmhwm_kb": 654116,
|
||||
"utime_ticks": 562,
|
||||
"stime_ticks": 28,
|
||||
"cg_current": 5983830016,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 6317,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 62172,
|
||||
"pty_writes": 31,
|
||||
"rss_kb": 656244,
|
||||
"pss_kb": 609320,
|
||||
"private_dirty_kb": 596124,
|
||||
"vmhwm_kb": 656244,
|
||||
"utime_ticks": 588,
|
||||
"stime_ticks": 28,
|
||||
"cg_current": 5982822400,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 6320,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 62172,
|
||||
"pty_writes": 31,
|
||||
"rss_kb": 656244,
|
||||
"pss_kb": 609320,
|
||||
"private_dirty_kb": 596124,
|
||||
"vmhwm_kb": 656244,
|
||||
"utime_ticks": 588,
|
||||
"stime_ticks": 28,
|
||||
"cg_current": 5982822400,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7067,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 66708,
|
||||
"pty_writes": 35,
|
||||
"rss_kb": 686948,
|
||||
"pss_kb": 640024,
|
||||
"private_dirty_kb": 626828,
|
||||
"vmhwm_kb": 686948,
|
||||
"utime_ticks": 662,
|
||||
"stime_ticks": 30,
|
||||
"cg_current": 5959647232,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 8074,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 66780,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 686956,
|
||||
"pss_kb": 640032,
|
||||
"private_dirty_kb": 626836,
|
||||
"vmhwm_kb": 686956,
|
||||
"utime_ticks": 663,
|
||||
"stime_ticks": 30,
|
||||
"cg_current": 5944725504,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 8123,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 66780,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 686956,
|
||||
"pss_kb": 640032,
|
||||
"private_dirty_kb": 626836,
|
||||
"vmhwm_kb": 686956,
|
||||
"utime_ticks": 663,
|
||||
"stime_ticks": 30,
|
||||
"cg_current": 5945589760,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 177
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "startup.catalog",
|
||||
"t_ms": 177
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "model.options",
|
||||
"t_ms": 202
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 9039
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 2000,
|
||||
"events_streamed": 7151,
|
||||
"pty_bytes_total": 71875,
|
||||
"pty_data_callbacks": 40,
|
||||
"first_byte_ms": 145,
|
||||
"session_create_ms": 177,
|
||||
"stream_start_ms": 1694,
|
||||
"vmhwm_kb": 686956,
|
||||
"cg_peak": 7893282816,
|
||||
"drain_max_loop_lag_ms": 10,
|
||||
"drain_lag_violations": 0,
|
||||
"drain_ok": true,
|
||||
"digest": null
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,594 @@
|
|||
{
|
||||
"meta": {
|
||||
"cell": "mem2000",
|
||||
"ui": "opentui",
|
||||
"config": "otui-uncapped",
|
||||
"mode": "mem",
|
||||
"rep": 0,
|
||||
"run_id": "mqaf9qba-ewsf",
|
||||
"utc": "2026-06-12T04:24:20.854Z",
|
||||
"sha": "f0ec24ad5",
|
||||
"node": "/home/daimon/.local/share/fnm/node-versions/v26.3.0/installation/bin/node",
|
||||
"node_version": "v26.3.0",
|
||||
"pty": {
|
||||
"cols": 120,
|
||||
"rows": 40,
|
||||
"term": "xterm-256color"
|
||||
},
|
||||
"heap_mb": 8192,
|
||||
"memory_max": "2G",
|
||||
"container_cap": false,
|
||||
"container_memory": null,
|
||||
"opentui_cap": 100000,
|
||||
"fixture": {
|
||||
"path": "/home/daimon/github/worktrees/hermes-agent/quiet-quill/hermes-agent/bench/.cache/fixture-2000.ndjson",
|
||||
"msgs": 2000,
|
||||
"sha256": "645b9ee4fdaccee45172fcec8af4a0b01a5f9aeca56ce45d8e84c4276472f99c"
|
||||
},
|
||||
"sample_every": 100,
|
||||
"mode_params": {},
|
||||
"ui_pid": 170071,
|
||||
"gw_pid": 170080,
|
||||
"cgroup": "/sys/fs/cgroup/user.slice/user-1001.slice/session-7349.scope",
|
||||
"load_avg_at_start": [
|
||||
0.65,
|
||||
0.9,
|
||||
1.38
|
||||
],
|
||||
"instrumented": false
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 26,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 0,
|
||||
"pty_writes": 0,
|
||||
"rss_kb": 35020,
|
||||
"pss_kb": 14276,
|
||||
"private_dirty_kb": 7704,
|
||||
"vmhwm_kb": 35152,
|
||||
"utime_ticks": 0,
|
||||
"stime_ticks": 0,
|
||||
"cg_current": 5950107648,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 1034,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 28909,
|
||||
"pty_writes": 12,
|
||||
"rss_kb": 104312,
|
||||
"pss_kb": 59828,
|
||||
"private_dirty_kb": 47852,
|
||||
"vmhwm_kb": 106556,
|
||||
"utime_ticks": 18,
|
||||
"stime_ticks": 3,
|
||||
"cg_current": 5950238720,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1712,
|
||||
"msgs": 100,
|
||||
"events": 355,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 111620,
|
||||
"pss_kb": 67014,
|
||||
"private_dirty_kb": 55036,
|
||||
"vmhwm_kb": 111736,
|
||||
"utime_ticks": 23,
|
||||
"stime_ticks": 3,
|
||||
"cg_current": 5950959616,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1713,
|
||||
"msgs": 200,
|
||||
"events": 738,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 111884,
|
||||
"pss_kb": 67278,
|
||||
"private_dirty_kb": 55300,
|
||||
"vmhwm_kb": 111980,
|
||||
"utime_ticks": 23,
|
||||
"stime_ticks": 3,
|
||||
"cg_current": 5950959616,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1714,
|
||||
"msgs": 300,
|
||||
"events": 1051,
|
||||
"pty_bytes": 31409,
|
||||
"pty_writes": 14,
|
||||
"rss_kb": 112096,
|
||||
"pss_kb": 67490,
|
||||
"private_dirty_kb": 55512,
|
||||
"vmhwm_kb": 112180,
|
||||
"utime_ticks": 23,
|
||||
"stime_ticks": 3,
|
||||
"cg_current": 5950734336,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 1991,
|
||||
"msgs": 400,
|
||||
"events": 1432,
|
||||
"pty_bytes": 32746,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 198544,
|
||||
"pss_kb": 151903,
|
||||
"private_dirty_kb": 138840,
|
||||
"vmhwm_kb": 198556,
|
||||
"utime_ticks": 67,
|
||||
"stime_ticks": 7,
|
||||
"cg_current": 5950930944,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 2040,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 32746,
|
||||
"pty_writes": 15,
|
||||
"rss_kb": 213612,
|
||||
"pss_kb": 166971,
|
||||
"private_dirty_kb": 153908,
|
||||
"vmhwm_kb": 213620,
|
||||
"utime_ticks": 74,
|
||||
"stime_ticks": 8,
|
||||
"cg_current": 5950930944,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2217,
|
||||
"msgs": 501,
|
||||
"events": 1792,
|
||||
"pty_bytes": 36888,
|
||||
"pty_writes": 17,
|
||||
"rss_kb": 236192,
|
||||
"pss_kb": 189448,
|
||||
"private_dirty_kb": 176308,
|
||||
"vmhwm_kb": 236244,
|
||||
"utime_ticks": 96,
|
||||
"stime_ticks": 9,
|
||||
"cg_current": 5955866624,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2416,
|
||||
"msgs": 601,
|
||||
"events": 2154,
|
||||
"pty_bytes": 41430,
|
||||
"pty_writes": 20,
|
||||
"rss_kb": 276612,
|
||||
"pss_kb": 229795,
|
||||
"private_dirty_kb": 216604,
|
||||
"vmhwm_kb": 276624,
|
||||
"utime_ticks": 127,
|
||||
"stime_ticks": 11,
|
||||
"cg_current": 5965406208,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2616,
|
||||
"msgs": 701,
|
||||
"events": 2496,
|
||||
"pty_bytes": 42632,
|
||||
"pty_writes": 21,
|
||||
"rss_kb": 347020,
|
||||
"pss_kb": 300087,
|
||||
"private_dirty_kb": 286888,
|
||||
"vmhwm_kb": 361648,
|
||||
"utime_ticks": 167,
|
||||
"stime_ticks": 14,
|
||||
"cg_current": 5960589312,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 2893,
|
||||
"msgs": 801,
|
||||
"events": 2857,
|
||||
"pty_bytes": 45204,
|
||||
"pty_writes": 23,
|
||||
"rss_kb": 377020,
|
||||
"pss_kb": 330087,
|
||||
"private_dirty_kb": 316888,
|
||||
"vmhwm_kb": 377020,
|
||||
"utime_ticks": 200,
|
||||
"stime_ticks": 15,
|
||||
"cg_current": 5960548352,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 3043,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 46835,
|
||||
"pty_writes": 24,
|
||||
"rss_kb": 403704,
|
||||
"pss_kb": 356768,
|
||||
"private_dirty_kb": 343572,
|
||||
"vmhwm_kb": 403784,
|
||||
"utime_ticks": 216,
|
||||
"stime_ticks": 17,
|
||||
"cg_current": 5960396800,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3193,
|
||||
"msgs": 901,
|
||||
"events": 3245,
|
||||
"pty_bytes": 48189,
|
||||
"pty_writes": 25,
|
||||
"rss_kb": 407960,
|
||||
"pss_kb": 361024,
|
||||
"private_dirty_kb": 347828,
|
||||
"vmhwm_kb": 407960,
|
||||
"utime_ticks": 232,
|
||||
"stime_ticks": 17,
|
||||
"cg_current": 5960396800,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3568,
|
||||
"msgs": 1001,
|
||||
"events": 3588,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 439108,
|
||||
"pss_kb": 392172,
|
||||
"private_dirty_kb": 378976,
|
||||
"vmhwm_kb": 439108,
|
||||
"utime_ticks": 276,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5960798208,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3572,
|
||||
"msgs": 1101,
|
||||
"events": 3928,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 439872,
|
||||
"pss_kb": 392936,
|
||||
"private_dirty_kb": 379740,
|
||||
"vmhwm_kb": 439876,
|
||||
"utime_ticks": 277,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5960798208,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3575,
|
||||
"msgs": 1201,
|
||||
"events": 4298,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 439880,
|
||||
"pss_kb": 392944,
|
||||
"private_dirty_kb": 379748,
|
||||
"vmhwm_kb": 439880,
|
||||
"utime_ticks": 277,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5960798208,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3577,
|
||||
"msgs": 1300,
|
||||
"events": 4659,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 439884,
|
||||
"pss_kb": 392948,
|
||||
"private_dirty_kb": 379752,
|
||||
"vmhwm_kb": 439888,
|
||||
"utime_ticks": 278,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5961322496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3579,
|
||||
"msgs": 1400,
|
||||
"events": 5011,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 439908,
|
||||
"pss_kb": 392972,
|
||||
"private_dirty_kb": 379776,
|
||||
"vmhwm_kb": 439908,
|
||||
"utime_ticks": 279,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5961322496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3581,
|
||||
"msgs": 1500,
|
||||
"events": 5384,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 440100,
|
||||
"pss_kb": 393164,
|
||||
"private_dirty_kb": 379968,
|
||||
"vmhwm_kb": 440128,
|
||||
"utime_ticks": 279,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5961322496,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3584,
|
||||
"msgs": 1600,
|
||||
"events": 5730,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 440320,
|
||||
"pss_kb": 393384,
|
||||
"private_dirty_kb": 380188,
|
||||
"vmhwm_kb": 440368,
|
||||
"utime_ticks": 280,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5961097216,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3586,
|
||||
"msgs": 1700,
|
||||
"events": 6100,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 440576,
|
||||
"pss_kb": 393640,
|
||||
"private_dirty_kb": 380444,
|
||||
"vmhwm_kb": 440656,
|
||||
"utime_ticks": 280,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5961097216,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 3588,
|
||||
"msgs": 1800,
|
||||
"events": 6455,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 440800,
|
||||
"pss_kb": 393864,
|
||||
"private_dirty_kb": 380668,
|
||||
"vmhwm_kb": 440888,
|
||||
"utime_ticks": 280,
|
||||
"stime_ticks": 19,
|
||||
"cg_current": 5961097216,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 4047,
|
||||
"msgs": null,
|
||||
"events": null,
|
||||
"pty_bytes": 53177,
|
||||
"pty_writes": 28,
|
||||
"rss_kb": 590428,
|
||||
"pss_kb": 543492,
|
||||
"private_dirty_kb": 530296,
|
||||
"vmhwm_kb": 590784,
|
||||
"utime_ticks": 362,
|
||||
"stime_ticks": 24,
|
||||
"cg_current": 5960552448,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 4423,
|
||||
"msgs": 1900,
|
||||
"events": 6838,
|
||||
"pty_bytes": 54671,
|
||||
"pty_writes": 29,
|
||||
"rss_kb": 632240,
|
||||
"pss_kb": 585304,
|
||||
"private_dirty_kb": 572108,
|
||||
"vmhwm_kb": 632296,
|
||||
"utime_ticks": 399,
|
||||
"stime_ticks": 25,
|
||||
"cg_current": 5960572928,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "boundary",
|
||||
"t_ms": 4826,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 55609,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 667328,
|
||||
"pss_kb": 620392,
|
||||
"private_dirty_kb": 607196,
|
||||
"vmhwm_kb": 667348,
|
||||
"utime_ticks": 441,
|
||||
"stime_ticks": 28,
|
||||
"cg_current": 5960556544,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "done",
|
||||
"t_ms": 4830,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 55609,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 667564,
|
||||
"pss_kb": 620628,
|
||||
"private_dirty_kb": 607432,
|
||||
"vmhwm_kb": 667572,
|
||||
"utime_ticks": 441,
|
||||
"stime_ticks": 28,
|
||||
"cg_current": 5960556544,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 5054,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 55609,
|
||||
"pty_writes": 30,
|
||||
"rss_kb": 692220,
|
||||
"pss_kb": 645284,
|
||||
"private_dirty_kb": 632088,
|
||||
"vmhwm_kb": 692220,
|
||||
"utime_ticks": 464,
|
||||
"stime_ticks": 31,
|
||||
"cg_current": 5940076544,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 6060,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 63491,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 710296,
|
||||
"pss_kb": 663360,
|
||||
"private_dirty_kb": 650164,
|
||||
"vmhwm_kb": 710296,
|
||||
"utime_ticks": 548,
|
||||
"stime_ticks": 32,
|
||||
"cg_current": 5940490240,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "final",
|
||||
"t_ms": 6700,
|
||||
"msgs": 2000,
|
||||
"events": 7151,
|
||||
"pty_bytes": 63491,
|
||||
"pty_writes": 36,
|
||||
"rss_kb": 710296,
|
||||
"pss_kb": 663360,
|
||||
"private_dirty_kb": 650164,
|
||||
"vmhwm_kb": 710296,
|
||||
"utime_ticks": 548,
|
||||
"stime_ticks": 32,
|
||||
"cg_current": 5940080640,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
},
|
||||
{
|
||||
"kind": "periodic",
|
||||
"t_ms": 7066,
|
||||
"msgs": 2000,
|
||||
"events": null,
|
||||
"pty_bytes": 68466,
|
||||
"pty_writes": 38,
|
||||
"rss_kb": 673924,
|
||||
"pss_kb": 626988,
|
||||
"private_dirty_kb": 613792,
|
||||
"vmhwm_kb": 709544,
|
||||
"utime_ticks": 574,
|
||||
"stime_ticks": 36,
|
||||
"cg_current": 5940109312,
|
||||
"cg_peak": 7893282816,
|
||||
"cg_oom_kill": 0
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "session.create",
|
||||
"t_ms": 202
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "startup.catalog",
|
||||
"t_ms": 202
|
||||
},
|
||||
{
|
||||
"kind": "rpc",
|
||||
"method": "model.options",
|
||||
"t_ms": 202
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"result": "completed",
|
||||
"cap_hit": false,
|
||||
"cap_hit_basis": null,
|
||||
"at_messages": null,
|
||||
"exit": {
|
||||
"exitCode": 0,
|
||||
"signal": 0,
|
||||
"t": 7613
|
||||
},
|
||||
"stream_done": true,
|
||||
"msgs_streamed": 2000,
|
||||
"events_streamed": 7151,
|
||||
"pty_bytes_total": 68586,
|
||||
"pty_data_callbacks": 40,
|
||||
"first_byte_ms": 146,
|
||||
"session_create_ms": 202,
|
||||
"stream_start_ms": 1686,
|
||||
"vmhwm_kb": 709544,
|
||||
"cg_peak": 7893282816,
|
||||
"drain_max_loop_lag_ms": 19,
|
||||
"drain_lag_violations": 1,
|
||||
"drain_ok": false,
|
||||
"digest": null
|
||||
}
|
||||
}
|
||||
1668
bench/results/2026-06-12T0425-f0ec24a-scroll2000-ink-ink-r0.json
Normal file
1668
bench/results/2026-06-12T0425-f0ec24a-scroll2000-ink-ink-r0.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1966
bench/results/2026-06-12T0426-f0ec24a-scroll2000-ink-ink-r1.json
Normal file
1966
bench/results/2026-06-12T0426-f0ec24a-scroll2000-ink-ink-r1.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1668
bench/results/2026-06-12T0429-f0ec24a-scroll2000-ink-ink-r2.json
Normal file
1668
bench/results/2026-06-12T0429-f0ec24a-scroll2000-ink-ink-r2.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1672,12 +1672,64 @@ def _node_version_tuple(node_bin: str) -> tuple[int, int, int] | None:
|
|||
return None
|
||||
|
||||
|
||||
def _fnm_node26_candidates() -> list[str]:
|
||||
"""Node binaries from fnm's installed versions, newest first.
|
||||
|
||||
fnm keeps each version at ``<FNM_DIR>/node-versions/v<X.Y.Z>/installation/
|
||||
bin/node`` (default ``FNM_DIR``: ``$XDG_DATA_HOME/fnm`` or ``~/.local/share/
|
||||
fnm``; macOS Homebrew also uses ``~/Library/Application Support/fnm``). When
|
||||
the *active* node is older than 26.3 — e.g. the user's fnm default is on
|
||||
v25 — the right 26.x is still installed and usable; surface it so OpenTUI
|
||||
works without the user re-aliasing their global default. Version-sorted so
|
||||
the newest qualifying node wins.
|
||||
"""
|
||||
roots: list[Path] = []
|
||||
fnm_dir = os.environ.get("FNM_DIR")
|
||||
if fnm_dir:
|
||||
roots.append(Path(fnm_dir))
|
||||
xdg = os.environ.get("XDG_DATA_HOME")
|
||||
if xdg:
|
||||
roots.append(Path(xdg) / "fnm")
|
||||
roots.append(Path.home() / ".local" / "share" / "fnm")
|
||||
roots.append(Path.home() / "Library" / "Application Support" / "fnm")
|
||||
|
||||
seen: set[Path] = set()
|
||||
found: list[tuple[tuple[int, int, int], str]] = []
|
||||
for root in roots:
|
||||
versions_dir = root / "node-versions"
|
||||
if versions_dir in seen or not versions_dir.is_dir():
|
||||
continue
|
||||
seen.add(versions_dir)
|
||||
try:
|
||||
entries = list(versions_dir.iterdir())
|
||||
except OSError:
|
||||
continue
|
||||
for entry in entries:
|
||||
node_bin = entry / "installation" / "bin" / "node"
|
||||
if not (node_bin.is_file() and os.access(node_bin, os.X_OK)):
|
||||
continue
|
||||
# Trust the directory name for sorting; the real probe happens in
|
||||
# the caller (a renamed/symlinked dir still gets version-checked).
|
||||
name = entry.name.lstrip("v").split("-", 1)[0]
|
||||
parts = name.split(".")
|
||||
try:
|
||||
ver = (int(parts[0]), int(parts[1]), int(parts[2]))
|
||||
except (IndexError, ValueError):
|
||||
ver = (0, 0, 0)
|
||||
found.append((ver, str(node_bin)))
|
||||
found.sort(key=lambda pair: pair[0], reverse=True)
|
||||
return [path for _, path in found]
|
||||
|
||||
|
||||
def _node26_bin_or_none() -> str | None:
|
||||
"""Resolve a Node >= 26.3.0 binary (no exit — a probe), or ``None``.
|
||||
|
||||
``HERMES_NODE`` override > ``node`` on PATH, each gated on version >= 26.3.0.
|
||||
OpenTUI's native renderer loads via the experimental ``node:ffi`` API that only
|
||||
exists on Node 26.3+, so an older Node is treated as "not available".
|
||||
Order: ``HERMES_NODE`` override > ``node`` on PATH > newest fnm-installed
|
||||
version. Each is gated on the real ``--version`` being >= 26.3.0. OpenTUI's
|
||||
native renderer loads via the experimental ``node:ffi`` API that only exists
|
||||
on Node 26.3+, so an older Node is treated as "not available" — but an
|
||||
installed-yet-inactive 26.x (common when fnm's default is on an older line)
|
||||
is discovered and used so the engine still launches.
|
||||
"""
|
||||
candidates: list[str] = []
|
||||
env_node = os.environ.get("HERMES_NODE")
|
||||
|
|
@ -1686,6 +1738,7 @@ def _node26_bin_or_none() -> str | None:
|
|||
path = shutil.which("node")
|
||||
if path:
|
||||
candidates.append(path)
|
||||
candidates.extend(_fnm_node26_candidates())
|
||||
for cand in candidates:
|
||||
ver = _node_version_tuple(cand)
|
||||
if ver is not None and ver >= NODE26_MIN_VERSION:
|
||||
|
|
@ -2122,6 +2175,14 @@ def _launch_tui(
|
|||
)
|
||||
env.setdefault("HERMES_PYTHON", sys.executable)
|
||||
env.setdefault("HERMES_CWD", os.getcwd())
|
||||
# The TUI subprocess is launched with cwd=<engine package dir> (so its
|
||||
# build/resolution works), which means the gateway it spawns would otherwise
|
||||
# auto-detect THAT dir as the workspace (chrome bar showed "ui-opentui" no
|
||||
# matter where you ran hermes). TERMINAL_CWD is the gateway's canonical
|
||||
# launch-dir channel (_completion_cwd) — set it to the real cwd here so the
|
||||
# session, chrome bar, and terminal tool all anchor to where you actually
|
||||
# are. Worktree mode overrides it to the worktree path below.
|
||||
env.setdefault("TERMINAL_CWD", os.getcwd())
|
||||
env.setdefault("NODE_ENV", "development" if tui_dev else "production")
|
||||
|
||||
wt_info = None
|
||||
|
|
|
|||
69
tests/hermes_cli/test_opentui_node_resolution.py
Normal file
69
tests/hermes_cli/test_opentui_node_resolution.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"""Node-26 resolution for the OpenTUI engine + the launch-cwd channel.
|
||||
|
||||
Regression coverage for two ways the local TUI silently fell back to Ink /
|
||||
showed the wrong directory:
|
||||
|
||||
1. fnm's active/default node was on an older line (v25) while a usable v26.3
|
||||
sat installed-but-inactive — ``_node26_bin_or_none`` only checked
|
||||
``HERMES_NODE`` + ``which node`` and so reported "no node 26" → OpenTUI
|
||||
unavailable → Ink fallback.
|
||||
2. ``TERMINAL_CWD`` (the gateway's launch-dir channel) was only exported in
|
||||
worktree mode, so a normal launch let the gateway auto-detect the engine's
|
||||
own package dir as the workspace.
|
||||
"""
|
||||
|
||||
import os
|
||||
import stat
|
||||
|
||||
import pytest
|
||||
|
||||
import hermes_cli.main as main_mod
|
||||
|
||||
|
||||
def _fake_node(path, version: str) -> None:
|
||||
"""Write a stub `node` that prints `version` for `--version`."""
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(f'#!/bin/sh\necho "{version}"\n')
|
||||
path.chmod(path.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
|
||||
|
||||
|
||||
class TestFnmNode26Discovery:
|
||||
def test_discovers_inactive_v26_when_default_is_older(self, tmp_path, monkeypatch):
|
||||
"""A v26.3 installed under fnm is found even when PATH `node` is v25."""
|
||||
fnm_dir = tmp_path / "fnm"
|
||||
for ver in ("24.11.0", "25.9.0", "26.3.0"):
|
||||
_fake_node(fnm_dir / "node-versions" / f"v{ver}" / "installation" / "bin" / "node", f"v{ver}")
|
||||
monkeypatch.setenv("FNM_DIR", str(fnm_dir))
|
||||
monkeypatch.delenv("HERMES_NODE", raising=False)
|
||||
# PATH node is the too-old default (v25).
|
||||
monkeypatch.setattr(main_mod.shutil, "which", lambda _b: str(
|
||||
fnm_dir / "node-versions" / "v25.9.0" / "installation" / "bin" / "node"
|
||||
))
|
||||
|
||||
resolved = main_mod._node26_bin_or_none()
|
||||
assert resolved is not None
|
||||
assert "v26.3.0" in resolved # newest qualifying, not the v25 default
|
||||
|
||||
def test_candidates_sorted_newest_first(self, tmp_path, monkeypatch):
|
||||
fnm_dir = tmp_path / "fnm"
|
||||
for ver in ("26.1.0", "26.4.0", "25.0.0"):
|
||||
_fake_node(fnm_dir / "node-versions" / f"v{ver}" / "installation" / "bin" / "node", f"v{ver}")
|
||||
monkeypatch.setenv("FNM_DIR", str(fnm_dir))
|
||||
cands = main_mod._fnm_node26_candidates()
|
||||
# Directory-name order: 26.4 before 26.1 before 25.0.
|
||||
idx = [next(i for i, c in enumerate(cands) if f"v{v}" in c) for v in ("26.4.0", "26.1.0", "25.0.0")]
|
||||
assert idx == sorted(idx)
|
||||
|
||||
def test_no_fnm_dir_is_empty_not_error(self, tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("FNM_DIR", str(tmp_path / "does-not-exist"))
|
||||
monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "xdg-none"))
|
||||
monkeypatch.setattr(main_mod.Path, "home", classmethod(lambda cls: tmp_path / "home-none"))
|
||||
assert main_mod._fnm_node26_candidates() == []
|
||||
|
||||
def test_hermes_node_still_wins(self, tmp_path, monkeypatch):
|
||||
"""An explicit HERMES_NODE >= 26.3 takes precedence over fnm discovery."""
|
||||
explicit = tmp_path / "explicit" / "node"
|
||||
_fake_node(explicit, "v26.5.0")
|
||||
monkeypatch.setenv("HERMES_NODE", str(explicit))
|
||||
monkeypatch.setattr(main_mod.shutil, "which", lambda _b: None)
|
||||
assert main_mod._node26_bin_or_none() == str(explicit)
|
||||
|
|
@ -3804,6 +3804,51 @@ def test_session_info_includes_mcp_servers(monkeypatch):
|
|||
assert info["mcp_servers"] == fake_status
|
||||
|
||||
|
||||
def test_session_info_includes_session_title(monkeypatch):
|
||||
"""session.info carries the live session title (window-title chrome).
|
||||
|
||||
Resolution order mirrors _session_live_title: DB row wins, a queued
|
||||
pending_title fills in before the row exists, "" until either lands.
|
||||
"""
|
||||
agent = types.SimpleNamespace(tools=[], model="m", provider="p")
|
||||
|
||||
# No session at all -> "" (and never a crash).
|
||||
assert server._session_info(agent, None)["title"] == ""
|
||||
|
||||
# pending_title before the DB row exists.
|
||||
session = {"session_key": "k1", "pending_title": "rename the moon"}
|
||||
monkeypatch.setattr(server, "_get_db", lambda: None)
|
||||
assert server._session_info(agent, session)["title"] == "rename the moon"
|
||||
|
||||
# DB row wins over pending.
|
||||
fake_db = types.SimpleNamespace(get_session_title=lambda key: "db title")
|
||||
monkeypatch.setattr(server, "_get_db", lambda: fake_db)
|
||||
assert server._session_info(agent, session)["title"] == "db title"
|
||||
|
||||
|
||||
def test_emit_title_refresh_pushes_session_info(monkeypatch):
|
||||
"""_emit_title_refresh emits a session.info for a live session and is a
|
||||
silent no-op for unknown/agent-less sessions (it runs on the auto-title
|
||||
worker thread -- it must never raise)."""
|
||||
events = []
|
||||
monkeypatch.setattr(
|
||||
server, "_emit", lambda event_type, sid, payload: events.append((event_type, sid, payload))
|
||||
)
|
||||
monkeypatch.setattr(server, "_session_info", lambda agent, session: {"title": "t"})
|
||||
|
||||
agent = types.SimpleNamespace(tools=[], model="m", provider="p")
|
||||
monkeypatch.setitem(server._sessions, "title-test", {"agent": agent, "session_key": "k"})
|
||||
|
||||
server._emit_title_refresh("title-test")
|
||||
assert events == [("session.info", "title-test", {"title": "t"})]
|
||||
|
||||
# Unknown sid / no agent -> no emission, no exception.
|
||||
server._emit_title_refresh("missing-sid")
|
||||
monkeypatch.setitem(server._sessions, "agentless", {"session_key": "k2"})
|
||||
server._emit_title_refresh("agentless")
|
||||
assert len(events) == 1
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# History-mutating commands must reject while session.running is True.
|
||||
# Without these guards, prompt.submit's post-run history write either
|
||||
|
|
|
|||
|
|
@ -2373,6 +2373,17 @@ def _session_info(agent, session: dict | None = None) -> dict:
|
|||
yolo = bool(_YOLO_MODE_FROZEN) or session_yolo or _get_approval_mode() == "off"
|
||||
except Exception:
|
||||
yolo = False
|
||||
# Session title (DB row, falling back to a not-yet-applied pending_title).
|
||||
# Drives client window-title chrome (OSC 0/2 in the native TUI); "" until
|
||||
# the first exchange titles the session.
|
||||
title = ""
|
||||
if session is not None:
|
||||
try:
|
||||
title = _session_live_title(
|
||||
session, str(session.get("session_key") or "")
|
||||
)
|
||||
except Exception:
|
||||
title = ""
|
||||
info: dict = {
|
||||
"model": getattr(agent, "model", ""),
|
||||
"provider": getattr(agent, "provider", ""),
|
||||
|
|
@ -2385,6 +2396,7 @@ def _session_info(agent, session: dict | None = None) -> dict:
|
|||
"cwd": cwd,
|
||||
"branch": _git_branch_for_cwd(cwd),
|
||||
"personality": str(personality or ""),
|
||||
"title": title,
|
||||
"running": bool((session or {}).get("running")),
|
||||
"desktop_contract": DESKTOP_BACKEND_CONTRACT,
|
||||
"version": "",
|
||||
|
|
@ -4399,6 +4411,22 @@ def _session_live_title(session: dict, key: str) -> str:
|
|||
return title
|
||||
|
||||
|
||||
def _emit_title_refresh(sid: str) -> None:
|
||||
"""Push a session.info refresh after a title change (pending-title
|
||||
application, auto-title landing, or a session.title rename) so clients'
|
||||
window-title chrome updates immediately. Thread-safe (auto-title calls
|
||||
this from its worker thread; _emit serializes on the stdout lock).
|
||||
Never raises."""
|
||||
try:
|
||||
session = _sessions.get(sid)
|
||||
agent = (session or {}).get("agent")
|
||||
if session is None or agent is None:
|
||||
return
|
||||
_emit("session.info", sid, _session_info(agent, session))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _session_live_item(sid: str, session: dict, current_sid: str = "") -> dict:
|
||||
key = str(session.get("session_key") or sid)
|
||||
agent = session.get("agent")
|
||||
|
|
@ -4624,15 +4652,18 @@ def _(rid, params: dict) -> dict:
|
|||
title = (params.get("title", "") or "").strip()
|
||||
if not title:
|
||||
return _err(rid, 4021, "title required")
|
||||
sid = str(params.get("session_id") or "")
|
||||
try:
|
||||
if db.set_session_title(key, title):
|
||||
session["pending_title"] = None
|
||||
_emit_title_refresh(sid)
|
||||
return _ok(rid, {"pending": False, "title": title})
|
||||
# rowcount == 0 can mean "same value" as well as "missing row".
|
||||
# Queue only when the session row truly does not exist yet.
|
||||
existing_row = db.get_session(key)
|
||||
if existing_row:
|
||||
session["pending_title"] = None
|
||||
_emit_title_refresh(sid)
|
||||
return _ok(
|
||||
rid,
|
||||
{
|
||||
|
|
@ -4641,6 +4672,7 @@ def _(rid, params: dict) -> dict:
|
|||
},
|
||||
)
|
||||
session["pending_title"] = title
|
||||
_emit_title_refresh(sid)
|
||||
return _ok(rid, {"pending": True, "title": title})
|
||||
except ValueError as e:
|
||||
return _err(rid, 4022, str(e))
|
||||
|
|
@ -5997,10 +6029,20 @@ def _run_prompt_submit(rid, sid: str, session: dict, text: Any) -> None:
|
|||
text,
|
||||
raw,
|
||||
session.get("history", []),
|
||||
# Auto-title lands on a background thread — refresh
|
||||
# session.info when it does so clients' window-title
|
||||
# chrome (OSC 0/2) updates without waiting for the
|
||||
# next turn. _emit is stdout-lock-guarded (thread-safe).
|
||||
title_callback=lambda _title: _emit_title_refresh(sid),
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# The pending title (applied synchronously above) is visible NOW —
|
||||
# refresh session.info so window-title chrome picks it up.
|
||||
if status == "complete" and _pending:
|
||||
_emit_title_refresh(sid)
|
||||
|
||||
# CLI parity: when voice-mode TTS is on, speak the agent reply
|
||||
# (cli.py:_voice_speak_response). Only the final text — tool
|
||||
# calls / reasoning already stream separately and would be
|
||||
|
|
|
|||
56
ui-opentui/parsers/bash/highlights.scm
Normal file
56
ui-opentui/parsers/bash/highlights.scm
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
[
|
||||
(string)
|
||||
(raw_string)
|
||||
(heredoc_body)
|
||||
(heredoc_start)
|
||||
] @string
|
||||
|
||||
(command_name) @function
|
||||
|
||||
(variable_name) @property
|
||||
|
||||
[
|
||||
"case"
|
||||
"do"
|
||||
"done"
|
||||
"elif"
|
||||
"else"
|
||||
"esac"
|
||||
"export"
|
||||
"fi"
|
||||
"for"
|
||||
"function"
|
||||
"if"
|
||||
"in"
|
||||
"select"
|
||||
"then"
|
||||
"unset"
|
||||
"until"
|
||||
"while"
|
||||
] @keyword
|
||||
|
||||
(comment) @comment
|
||||
|
||||
(function_definition name: (word) @function)
|
||||
|
||||
(file_descriptor) @number
|
||||
|
||||
[
|
||||
(command_substitution)
|
||||
(process_substitution)
|
||||
(expansion)
|
||||
]@embedded
|
||||
|
||||
[
|
||||
"$"
|
||||
"&&"
|
||||
">"
|
||||
">>"
|
||||
"<"
|
||||
"|"
|
||||
] @operator
|
||||
|
||||
(
|
||||
(command (_) @constant)
|
||||
(#match? @constant "^-")
|
||||
)
|
||||
BIN
ui-opentui/parsers/bash/tree-sitter-bash.wasm
Normal file
BIN
ui-opentui/parsers/bash/tree-sitter-bash.wasm
Normal file
Binary file not shown.
81
ui-opentui/parsers/c/highlights.scm
Normal file
81
ui-opentui/parsers/c/highlights.scm
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
(identifier) @variable
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
|
||||
|
||||
"break" @keyword
|
||||
"case" @keyword
|
||||
"const" @keyword
|
||||
"continue" @keyword
|
||||
"default" @keyword
|
||||
"do" @keyword
|
||||
"else" @keyword
|
||||
"enum" @keyword
|
||||
"extern" @keyword
|
||||
"for" @keyword
|
||||
"if" @keyword
|
||||
"inline" @keyword
|
||||
"return" @keyword
|
||||
"sizeof" @keyword
|
||||
"static" @keyword
|
||||
"struct" @keyword
|
||||
"switch" @keyword
|
||||
"typedef" @keyword
|
||||
"union" @keyword
|
||||
"volatile" @keyword
|
||||
"while" @keyword
|
||||
|
||||
"#define" @keyword
|
||||
"#elif" @keyword
|
||||
"#else" @keyword
|
||||
"#endif" @keyword
|
||||
"#if" @keyword
|
||||
"#ifdef" @keyword
|
||||
"#ifndef" @keyword
|
||||
"#include" @keyword
|
||||
(preproc_directive) @keyword
|
||||
|
||||
"--" @operator
|
||||
"-" @operator
|
||||
"-=" @operator
|
||||
"->" @operator
|
||||
"=" @operator
|
||||
"!=" @operator
|
||||
"*" @operator
|
||||
"&" @operator
|
||||
"&&" @operator
|
||||
"+" @operator
|
||||
"++" @operator
|
||||
"+=" @operator
|
||||
"<" @operator
|
||||
"==" @operator
|
||||
">" @operator
|
||||
"||" @operator
|
||||
|
||||
"." @delimiter
|
||||
";" @delimiter
|
||||
|
||||
(string_literal) @string
|
||||
(system_lib_string) @string
|
||||
|
||||
(null) @constant
|
||||
(number_literal) @number
|
||||
(char_literal) @number
|
||||
|
||||
(field_identifier) @property
|
||||
(statement_identifier) @label
|
||||
(type_identifier) @type
|
||||
(primitive_type) @type
|
||||
(sized_type_specifier) @type
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
(call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function))
|
||||
(function_declarator
|
||||
declarator: (identifier) @function)
|
||||
(preproc_function_def
|
||||
name: (identifier) @function.special)
|
||||
|
||||
(comment) @comment
|
||||
BIN
ui-opentui/parsers/c/tree-sitter-c.wasm
Normal file
BIN
ui-opentui/parsers/c/tree-sitter-c.wasm
Normal file
Binary file not shown.
64
ui-opentui/parsers/css/highlights.scm
Normal file
64
ui-opentui/parsers/css/highlights.scm
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
(comment) @comment
|
||||
|
||||
(tag_name) @tag
|
||||
(nesting_selector) @tag
|
||||
(universal_selector) @tag
|
||||
|
||||
"~" @operator
|
||||
">" @operator
|
||||
"+" @operator
|
||||
"-" @operator
|
||||
"*" @operator
|
||||
"/" @operator
|
||||
"=" @operator
|
||||
"^=" @operator
|
||||
"|=" @operator
|
||||
"~=" @operator
|
||||
"$=" @operator
|
||||
"*=" @operator
|
||||
|
||||
"and" @operator
|
||||
"or" @operator
|
||||
"not" @operator
|
||||
"only" @operator
|
||||
|
||||
(attribute_selector (plain_value) @string)
|
||||
(pseudo_element_selector (tag_name) @attribute)
|
||||
(pseudo_class_selector (class_name) @attribute)
|
||||
|
||||
(class_name) @property
|
||||
(id_name) @property
|
||||
(namespace_name) @property
|
||||
(property_name) @property
|
||||
(feature_name) @property
|
||||
|
||||
(attribute_name) @attribute
|
||||
|
||||
(function_name) @function
|
||||
|
||||
((property_name) @variable
|
||||
(#match? @variable "^--"))
|
||||
((plain_value) @variable
|
||||
(#match? @variable "^--"))
|
||||
|
||||
"@media" @keyword
|
||||
"@import" @keyword
|
||||
"@charset" @keyword
|
||||
"@namespace" @keyword
|
||||
"@supports" @keyword
|
||||
"@keyframes" @keyword
|
||||
(at_keyword) @keyword
|
||||
(to) @keyword
|
||||
(from) @keyword
|
||||
(important) @keyword
|
||||
|
||||
(string_value) @string
|
||||
(color_value) @string.special
|
||||
|
||||
(integer_value) @number
|
||||
(float_value) @number
|
||||
(unit) @type
|
||||
|
||||
"#" @punctuation.delimiter
|
||||
"," @punctuation.delimiter
|
||||
":" @punctuation.delimiter
|
||||
BIN
ui-opentui/parsers/css/tree-sitter-css.wasm
Normal file
BIN
ui-opentui/parsers/css/tree-sitter-css.wasm
Normal file
Binary file not shown.
123
ui-opentui/parsers/go/highlights.scm
Normal file
123
ui-opentui/parsers/go/highlights.scm
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
; Function calls
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function.builtin
|
||||
(#match? @function.builtin "^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)$"))
|
||||
|
||||
(call_expression
|
||||
function: (selector_expression
|
||||
field: (field_identifier) @function.method))
|
||||
|
||||
; Function definitions
|
||||
|
||||
(function_declaration
|
||||
name: (identifier) @function)
|
||||
|
||||
(method_declaration
|
||||
name: (field_identifier) @function.method)
|
||||
|
||||
; Identifiers
|
||||
|
||||
(type_identifier) @type
|
||||
(field_identifier) @property
|
||||
(identifier) @variable
|
||||
|
||||
; Operators
|
||||
|
||||
[
|
||||
"--"
|
||||
"-"
|
||||
"-="
|
||||
":="
|
||||
"!"
|
||||
"!="
|
||||
"..."
|
||||
"*"
|
||||
"*"
|
||||
"*="
|
||||
"/"
|
||||
"/="
|
||||
"&"
|
||||
"&&"
|
||||
"&="
|
||||
"%"
|
||||
"%="
|
||||
"^"
|
||||
"^="
|
||||
"+"
|
||||
"++"
|
||||
"+="
|
||||
"<-"
|
||||
"<"
|
||||
"<<"
|
||||
"<<="
|
||||
"<="
|
||||
"="
|
||||
"=="
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
">>="
|
||||
"|"
|
||||
"|="
|
||||
"||"
|
||||
"~"
|
||||
] @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"break"
|
||||
"case"
|
||||
"chan"
|
||||
"const"
|
||||
"continue"
|
||||
"default"
|
||||
"defer"
|
||||
"else"
|
||||
"fallthrough"
|
||||
"for"
|
||||
"func"
|
||||
"go"
|
||||
"goto"
|
||||
"if"
|
||||
"import"
|
||||
"interface"
|
||||
"map"
|
||||
"package"
|
||||
"range"
|
||||
"return"
|
||||
"select"
|
||||
"struct"
|
||||
"switch"
|
||||
"type"
|
||||
"var"
|
||||
] @keyword
|
||||
|
||||
; Literals
|
||||
|
||||
[
|
||||
(interpreted_string_literal)
|
||||
(raw_string_literal)
|
||||
(rune_literal)
|
||||
] @string
|
||||
|
||||
(escape_sequence) @escape
|
||||
|
||||
[
|
||||
(int_literal)
|
||||
(float_literal)
|
||||
(imaginary_literal)
|
||||
] @number
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
(nil)
|
||||
(iota)
|
||||
] @constant.builtin
|
||||
|
||||
(comment) @comment
|
||||
BIN
ui-opentui/parsers/go/tree-sitter-go.wasm
Normal file
BIN
ui-opentui/parsers/go/tree-sitter-go.wasm
Normal file
Binary file not shown.
13
ui-opentui/parsers/html/highlights.scm
Normal file
13
ui-opentui/parsers/html/highlights.scm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
(tag_name) @tag
|
||||
(erroneous_end_tag_name) @tag.error
|
||||
(doctype) @constant
|
||||
(attribute_name) @attribute
|
||||
(attribute_value) @string
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
"</"
|
||||
"/>"
|
||||
] @punctuation.bracket
|
||||
BIN
ui-opentui/parsers/html/tree-sitter-html.wasm
Normal file
BIN
ui-opentui/parsers/html/tree-sitter-html.wasm
Normal file
Binary file not shown.
16
ui-opentui/parsers/json/highlights.scm
Normal file
16
ui-opentui/parsers/json/highlights.scm
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(pair
|
||||
key: (_) @string.special.key)
|
||||
|
||||
(string) @string
|
||||
|
||||
(number) @number
|
||||
|
||||
[
|
||||
(null)
|
||||
(true)
|
||||
(false)
|
||||
] @constant.builtin
|
||||
|
||||
(escape_sequence) @escape
|
||||
|
||||
(comment) @comment
|
||||
BIN
ui-opentui/parsers/json/tree-sitter-json.wasm
Normal file
BIN
ui-opentui/parsers/json/tree-sitter-json.wasm
Normal file
Binary file not shown.
15
ui-opentui/parsers/manifest.json
Normal file
15
ui-opentui/parsers/manifest.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"comment": "Tree-sitter grammars vendored beyond @opentui/core's bundled 5 (ts/js/markdown/markdown_inline/zig). Source of truth for scripts/update-parsers.mjs (vendoring) and src/boundary/parsers.ts (boot registration). Curated in docs/plans/opentui-syntax-highlighting-languages.md — cpp deliberately dropped (3.28 MB, ~half the bundle). Aliases are belt-and-braces: core's extToFiletype/infoStringToFiletype already normalize py->python etc., but a literal alias filetype reaching the client still resolves.",
|
||||
"parsers": [
|
||||
{ "filetype": "python", "aliases": ["py"], "org": "tree-sitter", "tag": "v0.23.6" },
|
||||
{ "filetype": "rust", "aliases": ["rs"], "org": "tree-sitter", "tag": "v0.23.2" },
|
||||
{ "filetype": "go", "aliases": [], "org": "tree-sitter", "tag": "v0.23.4" },
|
||||
{ "filetype": "bash", "aliases": ["sh", "shell", "zsh"], "org": "tree-sitter", "tag": "v0.23.3" },
|
||||
{ "filetype": "json", "aliases": [], "org": "tree-sitter", "tag": "v0.24.8" },
|
||||
{ "filetype": "c", "aliases": ["h"], "org": "tree-sitter", "tag": "v0.23.5" },
|
||||
{ "filetype": "html", "aliases": [], "org": "tree-sitter", "tag": "v0.23.2" },
|
||||
{ "filetype": "css", "aliases": [], "org": "tree-sitter", "tag": "v0.23.2" },
|
||||
{ "filetype": "yaml", "aliases": ["yml"], "org": "tree-sitter-grammars", "tag": "v0.7.1" },
|
||||
{ "filetype": "toml", "aliases": [], "org": "tree-sitter-grammars", "tag": "v0.7.0" }
|
||||
]
|
||||
}
|
||||
137
ui-opentui/parsers/python/highlights.scm
Normal file
137
ui-opentui/parsers/python/highlights.scm
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
; Identifier naming conventions
|
||||
|
||||
(identifier) @variable
|
||||
|
||||
((identifier) @constructor
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z_]*$"))
|
||||
|
||||
; Function calls
|
||||
|
||||
(decorator) @function
|
||||
(decorator
|
||||
(identifier) @function)
|
||||
|
||||
(call
|
||||
function: (attribute attribute: (identifier) @function.method))
|
||||
(call
|
||||
function: (identifier) @function)
|
||||
|
||||
; Builtin functions
|
||||
|
||||
((call
|
||||
function: (identifier) @function.builtin)
|
||||
(#match?
|
||||
@function.builtin
|
||||
"^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
|
||||
|
||||
; Function definitions
|
||||
|
||||
(function_definition
|
||||
name: (identifier) @function)
|
||||
|
||||
(attribute attribute: (identifier) @property)
|
||||
(type (identifier) @type)
|
||||
|
||||
; Literals
|
||||
|
||||
[
|
||||
(none)
|
||||
(true)
|
||||
(false)
|
||||
] @constant.builtin
|
||||
|
||||
[
|
||||
(integer)
|
||||
(float)
|
||||
] @number
|
||||
|
||||
(comment) @comment
|
||||
(string) @string
|
||||
(escape_sequence) @escape
|
||||
|
||||
(interpolation
|
||||
"{" @punctuation.special
|
||||
"}" @punctuation.special) @embedded
|
||||
|
||||
[
|
||||
"-"
|
||||
"-="
|
||||
"!="
|
||||
"*"
|
||||
"**"
|
||||
"**="
|
||||
"*="
|
||||
"/"
|
||||
"//"
|
||||
"//="
|
||||
"/="
|
||||
"&"
|
||||
"&="
|
||||
"%"
|
||||
"%="
|
||||
"^"
|
||||
"^="
|
||||
"+"
|
||||
"->"
|
||||
"+="
|
||||
"<"
|
||||
"<<"
|
||||
"<<="
|
||||
"<="
|
||||
"<>"
|
||||
"="
|
||||
":="
|
||||
"=="
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
">>="
|
||||
"|"
|
||||
"|="
|
||||
"~"
|
||||
"@="
|
||||
"and"
|
||||
"in"
|
||||
"is"
|
||||
"not"
|
||||
"or"
|
||||
"is not"
|
||||
"not in"
|
||||
] @operator
|
||||
|
||||
[
|
||||
"as"
|
||||
"assert"
|
||||
"async"
|
||||
"await"
|
||||
"break"
|
||||
"class"
|
||||
"continue"
|
||||
"def"
|
||||
"del"
|
||||
"elif"
|
||||
"else"
|
||||
"except"
|
||||
"exec"
|
||||
"finally"
|
||||
"for"
|
||||
"from"
|
||||
"global"
|
||||
"if"
|
||||
"import"
|
||||
"lambda"
|
||||
"nonlocal"
|
||||
"pass"
|
||||
"print"
|
||||
"raise"
|
||||
"return"
|
||||
"try"
|
||||
"while"
|
||||
"with"
|
||||
"yield"
|
||||
"match"
|
||||
"case"
|
||||
] @keyword
|
||||
BIN
ui-opentui/parsers/python/tree-sitter-python.wasm
Normal file
BIN
ui-opentui/parsers/python/tree-sitter-python.wasm
Normal file
Binary file not shown.
161
ui-opentui/parsers/rust/highlights.scm
Normal file
161
ui-opentui/parsers/rust/highlights.scm
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
; Identifiers
|
||||
|
||||
(type_identifier) @type
|
||||
(primitive_type) @type.builtin
|
||||
(field_identifier) @property
|
||||
|
||||
; Identifier conventions
|
||||
|
||||
; Assume all-caps names are constants
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z\\d_]+$'"))
|
||||
|
||||
; Assume uppercase names are enum constructors
|
||||
((identifier) @constructor
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
; Assume that uppercase names in paths are types
|
||||
((scoped_identifier
|
||||
path: (identifier) @type)
|
||||
(#match? @type "^[A-Z]"))
|
||||
((scoped_identifier
|
||||
path: (scoped_identifier
|
||||
name: (identifier) @type))
|
||||
(#match? @type "^[A-Z]"))
|
||||
((scoped_type_identifier
|
||||
path: (identifier) @type)
|
||||
(#match? @type "^[A-Z]"))
|
||||
((scoped_type_identifier
|
||||
path: (scoped_identifier
|
||||
name: (identifier) @type))
|
||||
(#match? @type "^[A-Z]"))
|
||||
|
||||
; Assume all qualified names in struct patterns are enum constructors. (They're
|
||||
; either that, or struct names; highlighting both as constructors seems to be
|
||||
; the less glaring choice of error, visually.)
|
||||
(struct_pattern
|
||||
type: (scoped_type_identifier
|
||||
name: (type_identifier) @constructor))
|
||||
|
||||
; Function calls
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
(call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function.method))
|
||||
(call_expression
|
||||
function: (scoped_identifier
|
||||
"::"
|
||||
name: (identifier) @function))
|
||||
|
||||
(generic_function
|
||||
function: (identifier) @function)
|
||||
(generic_function
|
||||
function: (scoped_identifier
|
||||
name: (identifier) @function))
|
||||
(generic_function
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function.method))
|
||||
|
||||
(macro_invocation
|
||||
macro: (identifier) @function.macro
|
||||
"!" @function.macro)
|
||||
|
||||
; Function definitions
|
||||
|
||||
(function_item (identifier) @function)
|
||||
(function_signature_item (identifier) @function)
|
||||
|
||||
(line_comment) @comment
|
||||
(block_comment) @comment
|
||||
|
||||
(line_comment (doc_comment)) @comment.documentation
|
||||
(block_comment (doc_comment)) @comment.documentation
|
||||
|
||||
"(" @punctuation.bracket
|
||||
")" @punctuation.bracket
|
||||
"[" @punctuation.bracket
|
||||
"]" @punctuation.bracket
|
||||
"{" @punctuation.bracket
|
||||
"}" @punctuation.bracket
|
||||
|
||||
(type_arguments
|
||||
"<" @punctuation.bracket
|
||||
">" @punctuation.bracket)
|
||||
(type_parameters
|
||||
"<" @punctuation.bracket
|
||||
">" @punctuation.bracket)
|
||||
|
||||
"::" @punctuation.delimiter
|
||||
":" @punctuation.delimiter
|
||||
"." @punctuation.delimiter
|
||||
"," @punctuation.delimiter
|
||||
";" @punctuation.delimiter
|
||||
|
||||
(parameter (identifier) @variable.parameter)
|
||||
|
||||
(lifetime (identifier) @label)
|
||||
|
||||
"as" @keyword
|
||||
"async" @keyword
|
||||
"await" @keyword
|
||||
"break" @keyword
|
||||
"const" @keyword
|
||||
"continue" @keyword
|
||||
"default" @keyword
|
||||
"dyn" @keyword
|
||||
"else" @keyword
|
||||
"enum" @keyword
|
||||
"extern" @keyword
|
||||
"fn" @keyword
|
||||
"for" @keyword
|
||||
"gen" @keyword
|
||||
"if" @keyword
|
||||
"impl" @keyword
|
||||
"in" @keyword
|
||||
"let" @keyword
|
||||
"loop" @keyword
|
||||
"macro_rules!" @keyword
|
||||
"match" @keyword
|
||||
"mod" @keyword
|
||||
"move" @keyword
|
||||
"pub" @keyword
|
||||
"raw" @keyword
|
||||
"ref" @keyword
|
||||
"return" @keyword
|
||||
"static" @keyword
|
||||
"struct" @keyword
|
||||
"trait" @keyword
|
||||
"type" @keyword
|
||||
"union" @keyword
|
||||
"unsafe" @keyword
|
||||
"use" @keyword
|
||||
"where" @keyword
|
||||
"while" @keyword
|
||||
"yield" @keyword
|
||||
(crate) @keyword
|
||||
(mutable_specifier) @keyword
|
||||
(use_list (self) @keyword)
|
||||
(scoped_use_list (self) @keyword)
|
||||
(scoped_identifier (self) @keyword)
|
||||
(super) @keyword
|
||||
|
||||
(self) @variable.builtin
|
||||
|
||||
(char_literal) @string
|
||||
(string_literal) @string
|
||||
(raw_string_literal) @string
|
||||
|
||||
(boolean_literal) @constant.builtin
|
||||
(integer_literal) @constant.builtin
|
||||
(float_literal) @constant.builtin
|
||||
|
||||
(escape_sequence) @escape
|
||||
|
||||
(attribute_item) @attribute
|
||||
(inner_attribute_item) @attribute
|
||||
|
||||
"*" @operator
|
||||
"&" @operator
|
||||
"'" @operator
|
||||
BIN
ui-opentui/parsers/rust/tree-sitter-rust.wasm
Normal file
BIN
ui-opentui/parsers/rust/tree-sitter-rust.wasm
Normal file
Binary file not shown.
53
ui-opentui/parsers/toml/highlights.scm
Normal file
53
ui-opentui/parsers/toml/highlights.scm
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
; Properties
|
||||
;-----------
|
||||
|
||||
(bare_key) @type
|
||||
|
||||
(quoted_key) @string
|
||||
|
||||
(pair
|
||||
(bare_key)) @property
|
||||
|
||||
(pair
|
||||
(dotted_key
|
||||
(bare_key) @property))
|
||||
|
||||
; Literals
|
||||
;---------
|
||||
|
||||
(boolean) @boolean
|
||||
|
||||
(comment) @comment
|
||||
|
||||
(string) @string
|
||||
|
||||
[
|
||||
(integer)
|
||||
(float)
|
||||
] @number
|
||||
|
||||
[
|
||||
(offset_date_time)
|
||||
(local_date_time)
|
||||
(local_date)
|
||||
(local_time)
|
||||
] @string.special
|
||||
|
||||
; Punctuation
|
||||
;------------
|
||||
|
||||
[
|
||||
"."
|
||||
","
|
||||
] @punctuation.delimiter
|
||||
|
||||
"=" @operator
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
"[["
|
||||
"]]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
BIN
ui-opentui/parsers/toml/tree-sitter-toml.wasm
Normal file
BIN
ui-opentui/parsers/toml/tree-sitter-toml.wasm
Normal file
Binary file not shown.
79
ui-opentui/parsers/yaml/highlights.scm
Normal file
79
ui-opentui/parsers/yaml/highlights.scm
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
(boolean_scalar) @boolean
|
||||
|
||||
(null_scalar) @constant.builtin
|
||||
|
||||
[
|
||||
(double_quote_scalar)
|
||||
(single_quote_scalar)
|
||||
(block_scalar)
|
||||
(string_scalar)
|
||||
] @string
|
||||
|
||||
[
|
||||
(integer_scalar)
|
||||
(float_scalar)
|
||||
] @number
|
||||
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
(anchor_name)
|
||||
(alias_name)
|
||||
] @label
|
||||
|
||||
(tag) @type
|
||||
|
||||
[
|
||||
(yaml_directive)
|
||||
(tag_directive)
|
||||
(reserved_directive)
|
||||
] @attribute
|
||||
|
||||
(block_mapping_pair
|
||||
key: (flow_node
|
||||
[
|
||||
(double_quote_scalar)
|
||||
(single_quote_scalar)
|
||||
] @property))
|
||||
|
||||
(block_mapping_pair
|
||||
key: (flow_node
|
||||
(plain_scalar
|
||||
(string_scalar) @property)))
|
||||
|
||||
(flow_mapping
|
||||
(_
|
||||
key: (flow_node
|
||||
[
|
||||
(double_quote_scalar)
|
||||
(single_quote_scalar)
|
||||
] @property)))
|
||||
|
||||
(flow_mapping
|
||||
(_
|
||||
key: (flow_node
|
||||
(plain_scalar
|
||||
(string_scalar) @property))))
|
||||
|
||||
[
|
||||
","
|
||||
"-"
|
||||
":"
|
||||
">"
|
||||
"?"
|
||||
"|"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
"*"
|
||||
"&"
|
||||
"---"
|
||||
"..."
|
||||
] @punctuation.special
|
||||
BIN
ui-opentui/parsers/yaml/tree-sitter-yaml.wasm
Normal file
BIN
ui-opentui/parsers/yaml/tree-sitter-yaml.wasm
Normal file
Binary file not shown.
|
|
@ -16,11 +16,15 @@ import { createCliRenderer } from '@opentui/core'
|
|||
import { render } from '@opentui/solid'
|
||||
|
||||
import { installMultiClickSelection } from '../src/boundary/multiClickSelect.ts'
|
||||
import { registerVendoredParsers } from '../src/boundary/parsers.ts'
|
||||
import { createSessionStore } from '../src/logic/store.ts'
|
||||
import { App } from '../src/view/App.tsx'
|
||||
import { ThemeProvider } from '../src/view/theme.tsx'
|
||||
import { materialize } from './fixture.ts'
|
||||
|
||||
// Same grammar registration as the live entry so fixture code blocks highlight.
|
||||
registerVendoredParsers()
|
||||
|
||||
const TOTAL = Number.parseInt(process.env.DEMO_TOTAL ?? '', 10) || 200
|
||||
|
||||
const store = createSessionStore()
|
||||
|
|
|
|||
71
ui-opentui/scripts/update-parsers.mjs
Normal file
71
ui-opentui/scripts/update-parsers.mjs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* Vendor the extra Tree-sitter grammars listed in parsers/manifest.json into
|
||||
* parsers/<filetype>/ (wasm + highlights.scm). Plain Node fetch — no Bun
|
||||
* (core's update-assets.js is bun-shebanged; its download logic is just
|
||||
* fetch+fs, so we do the same two writes ourselves and keep the generated
|
||||
* import-module out of the esbuild bundle entirely — registration reads the
|
||||
* vendored files by PATH at runtime, see src/boundary/parsers.ts).
|
||||
*
|
||||
* Idempotent: existing valid files are kept unless --force. Validates wasm
|
||||
* magic and a non-empty query so a bad download can never be committed.
|
||||
*
|
||||
* node scripts/update-parsers.mjs [--force]
|
||||
*
|
||||
* The vendored files are COMMITTED (build inputs, like @opentui/core's own
|
||||
* assets/) — builds and offline machines never re-download.
|
||||
*/
|
||||
import { Buffer } from 'node:buffer'
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import { dirname, join, resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const parsersDir = join(root, 'parsers')
|
||||
const force = process.argv.includes('--force')
|
||||
|
||||
const manifest = JSON.parse(await readFile(join(parsersDir, 'manifest.json'), 'utf8'))
|
||||
|
||||
const wasmUrl = p =>
|
||||
`https://github.com/${p.org}/tree-sitter-${p.filetype}/releases/download/${p.tag}/tree-sitter-${p.filetype}.wasm`
|
||||
const scmUrl = p =>
|
||||
`https://raw.githubusercontent.com/${p.org}/tree-sitter-${p.filetype}/${p.tag}/queries/highlights.scm`
|
||||
|
||||
async function fetchBytes(url) {
|
||||
const response = await globalThis.fetch(url)
|
||||
if (!response.ok) throw new Error(`${response.status} ${response.statusText} for ${url}`)
|
||||
return Buffer.from(await response.arrayBuffer())
|
||||
}
|
||||
|
||||
async function haveValid(path, validate) {
|
||||
try {
|
||||
return validate(await readFile(path))
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const isWasm = bytes => bytes.length > 8 && bytes.subarray(0, 4).toString('latin1') === '\0asm'
|
||||
const isQuery = bytes => bytes.length > 0 && bytes.toString('utf8').trim().length > 0
|
||||
|
||||
let downloaded = 0
|
||||
for (const parser of manifest.parsers) {
|
||||
const dir = join(parsersDir, parser.filetype)
|
||||
await mkdir(dir, { recursive: true })
|
||||
const targets = [
|
||||
{ name: `tree-sitter-${parser.filetype}.wasm`, url: wasmUrl(parser), validate: isWasm },
|
||||
{ name: 'highlights.scm', url: scmUrl(parser), validate: isQuery }
|
||||
]
|
||||
for (const target of targets) {
|
||||
const path = join(dir, target.name)
|
||||
if (!force && (await haveValid(path, target.validate))) {
|
||||
console.log(`✓ kept ${parser.filetype}/${target.name}`)
|
||||
continue
|
||||
}
|
||||
const bytes = await fetchBytes(target.url)
|
||||
if (!target.validate(bytes)) throw new Error(`validation failed for ${target.url}`)
|
||||
await writeFile(path, bytes)
|
||||
downloaded += 1
|
||||
console.log(`↓ fetched ${parser.filetype}/${target.name} (${(bytes.length / 1024).toFixed(0)} KB)`)
|
||||
}
|
||||
}
|
||||
console.log(`done — ${downloaded} file(s) fetched, ${manifest.parsers.length} grammars vendored`)
|
||||
93
ui-opentui/src/boundary/parsers.ts
Normal file
93
ui-opentui/src/boundary/parsers.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* Extra Tree-sitter grammar registration — the syntax-highlighting language
|
||||
* expansion (docs/plans/opentui-syntax-highlighting-languages.md).
|
||||
*
|
||||
* @opentui/core@0.4.0 bundles only 5 grammars (ts/js/markdown/markdown_inline/
|
||||
* zig); everything else rendered plain text. The cure is the public
|
||||
* `addDefaultParsers()` API + the grammars vendored under `parsers/<filetype>/`
|
||||
* (committed; refresh via `node scripts/update-parsers.mjs`).
|
||||
*
|
||||
* Why paths, not the generated import-module: core's `updateAssets` generates
|
||||
* a Bun-flavored module (`import(... { with: { type: "file" } })`) that esbuild
|
||||
* can't bundle; its own Node fallback resolves plain file paths anyway, and
|
||||
* `FiletypeParserOptions.wasm`/`queries.highlights` accept local paths
|
||||
* directly. So registration just points at the vendored files — resolved at
|
||||
* RUNTIME by walking up from this module to the package root, which works from
|
||||
* both the esbuild bundle (dist/main.js → ../parsers) and vitest's src tree
|
||||
* (src/boundary → ../../parsers).
|
||||
*
|
||||
* Must run BEFORE the first `<code>`/`<markdown>` mount (they grab the global
|
||||
* tree-sitter client lazily) — the entry imports + calls this at module load,
|
||||
* ahead of renderer acquisition. Total: a missing assets dir degrades to
|
||||
* core's bundled set (plain text for the extras), never a throw.
|
||||
*/
|
||||
import { existsSync } from 'node:fs'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { addDefaultParsers } from '@opentui/core'
|
||||
|
||||
import manifest from '../../parsers/manifest.json'
|
||||
import { getLog } from './log.ts'
|
||||
|
||||
interface ManifestParser {
|
||||
readonly filetype: string
|
||||
readonly aliases: readonly string[]
|
||||
}
|
||||
|
||||
/** The registered parser configs (exported shape for tests/diagnostics). */
|
||||
export interface RegisteredParser {
|
||||
filetype: string
|
||||
aliases?: string[]
|
||||
wasm: string
|
||||
queries: { highlights: string[] }
|
||||
}
|
||||
|
||||
/** Walk up from this module (bundle: dist/…; tests: src/boundary/…) to the
|
||||
* package root's vendored `parsers/` dir. */
|
||||
function findParsersDir(): string | undefined {
|
||||
let dir = dirname(fileURLToPath(import.meta.url))
|
||||
for (let hop = 0; hop < 5; hop += 1) {
|
||||
const candidate = join(dir, 'parsers')
|
||||
if (existsSync(join(candidate, 'manifest.json'))) return candidate
|
||||
dir = dirname(dir)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
/** Build the parser configs for every vendored grammar whose files exist. */
|
||||
export function vendoredParsers(parsersDir: string | undefined = findParsersDir()): RegisteredParser[] {
|
||||
if (!parsersDir) return []
|
||||
const configs: RegisteredParser[] = []
|
||||
for (const parser of (manifest as { parsers: ManifestParser[] }).parsers) {
|
||||
const wasm = join(parsersDir, parser.filetype, `tree-sitter-${parser.filetype}.wasm`)
|
||||
const highlights = join(parsersDir, parser.filetype, 'highlights.scm')
|
||||
if (!existsSync(wasm) || !existsSync(highlights)) continue
|
||||
configs.push({
|
||||
filetype: parser.filetype,
|
||||
...(parser.aliases.length ? { aliases: [...parser.aliases] } : {}),
|
||||
wasm,
|
||||
queries: { highlights: [highlights] }
|
||||
})
|
||||
}
|
||||
return configs
|
||||
}
|
||||
|
||||
/** Register the vendored grammars with core's global default-parser list.
|
||||
* Returns what was registered (empty on any failure — plain-text fallback). */
|
||||
export function registerVendoredParsers(): RegisteredParser[] {
|
||||
try {
|
||||
const parsers = vendoredParsers()
|
||||
if (!parsers.length) {
|
||||
getLog().warn('parsers', 'no vendored tree-sitter grammars found — extras render plain', {})
|
||||
return []
|
||||
}
|
||||
addDefaultParsers(parsers)
|
||||
return parsers
|
||||
} catch (cause) {
|
||||
getLog().warn('parsers', 'tree-sitter registration failed — extras render plain', {
|
||||
cause: String(cause)
|
||||
})
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
|
@ -52,6 +52,9 @@ export const SessionInfoPatchSchema = Schema.Struct({
|
|||
fast: opt(Bool),
|
||||
cwd: opt(Str),
|
||||
branch: opt(Str),
|
||||
// session title ("" until the first exchange titles it) — drives the
|
||||
// terminal window-title chrome (OSC 0/2 via renderer.setTerminalTitle).
|
||||
title: opt(Str),
|
||||
running: opt(Bool),
|
||||
// status-bar chrome extras (Epic 1.3): update banner, profile badge, MCP count.
|
||||
// `update_behind` is null on the wire until the async update check resolves.
|
||||
|
|
|
|||
106
ui-opentui/src/boundary/termChrome.ts
Normal file
106
ui-opentui/src/boundary/termChrome.ts
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Terminal chrome seam — window title (OSC 0/2) + desktop notifications
|
||||
* (OSC 9/99/777) through the renderer's native output path.
|
||||
*
|
||||
* Why the renderer and not process.stdout: the zig side owns the terminal —
|
||||
* `setTerminalTitle` is a native FFI call and `writeOut` serializes raw
|
||||
* control bytes with frame presentation (core itself uses it for OSC 111),
|
||||
* so chrome writes can never tear a frame.
|
||||
*
|
||||
* Focus suppression: core parses mode-1004 focus reports (`ESC[I`/`ESC[O`)
|
||||
* and re-emits them as renderer `focus`/`blur` events — notifications are
|
||||
* skipped while the terminal reports focused (you're already looking at it).
|
||||
* Terminals that never report focus leave the state at the assumed-focused
|
||||
* initial value… which would swallow every notification, so the FIRST blur
|
||||
* is what arms suppression: until a blur arrives we treat focus as unknown
|
||||
* and notify unconditionally (worst case: a redundant ping while focused).
|
||||
*
|
||||
* Everything here is total — chrome must never throw into the render loop
|
||||
* or a teardown path.
|
||||
*/
|
||||
import type { CliRenderer } from '@opentui/core'
|
||||
|
||||
import type { TermNotification } from '../logic/termChrome.ts'
|
||||
import {
|
||||
notifyEnabled,
|
||||
notifySequences,
|
||||
TITLE_STACK_RESTORE,
|
||||
TITLE_STACK_SAVE,
|
||||
windowTitleFor
|
||||
} from '../logic/termChrome.ts'
|
||||
import { getLog } from './log.ts'
|
||||
|
||||
/** What the view layer needs from the chrome seam (DI-friendly for tests). */
|
||||
export interface TerminalChromeSeam {
|
||||
/** Set the window title from the session title (undefined → generic). */
|
||||
readonly setTitle: (sessionTitle: string | undefined) => void
|
||||
/** Announce "waiting on you" to the hosting terminal (no-op while focused). */
|
||||
readonly notify: (notification: TermNotification) => void
|
||||
}
|
||||
|
||||
/** The renderer surface the seam writes through (runtime-verified shapes). */
|
||||
interface RendererSeam {
|
||||
setTerminalTitle(title: string): void
|
||||
writeOut(chunk: string): void
|
||||
on(event: 'focus' | 'blur', listener: () => void): unknown
|
||||
once(event: 'destroy', listener: () => void): unknown
|
||||
readonly isDestroyed: boolean
|
||||
}
|
||||
|
||||
/** Install the chrome seam on a live renderer. Idempotent per renderer use —
|
||||
* the entry calls it once, right next to the render bridge. */
|
||||
export function installTerminalChrome(renderer: CliRenderer): TerminalChromeSeam {
|
||||
const seam = renderer as unknown as RendererSeam
|
||||
const notificationsOn = notifyEnabled()
|
||||
|
||||
// unknown (null) until the terminal proves it reports focus; then boolean.
|
||||
let focused: boolean | null = null
|
||||
try {
|
||||
seam.on('focus', () => {
|
||||
focused = true
|
||||
})
|
||||
seam.on('blur', () => {
|
||||
focused = false
|
||||
})
|
||||
} catch (cause) {
|
||||
getLog().warn('chrome', 'focus tracking unavailable', { cause: String(cause) })
|
||||
}
|
||||
|
||||
// Bracket our title ownership: save the user's title now, restore on quit.
|
||||
// Best-effort — terminals without the XTWINOPS title stack ignore both.
|
||||
writeRaw(seam, TITLE_STACK_SAVE)
|
||||
seam.once('destroy', () => writeRaw(seam, TITLE_STACK_RESTORE, { evenIfDestroyed: true }))
|
||||
|
||||
let lastTitle = ''
|
||||
return {
|
||||
setTitle: sessionTitle => {
|
||||
const title = windowTitleFor(sessionTitle)
|
||||
if (title === lastTitle) return
|
||||
lastTitle = title
|
||||
try {
|
||||
if (!seam.isDestroyed) seam.setTerminalTitle(title)
|
||||
} catch (cause) {
|
||||
getLog().warn('chrome', 'setTerminalTitle failed', { cause: String(cause) })
|
||||
}
|
||||
},
|
||||
notify: notification => {
|
||||
if (!notificationsOn || focused === true) return
|
||||
for (const sequence of notifySequences(notification)) writeRaw(seam, sequence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Raw control write through the renderer; falls back to process.stdout when
|
||||
* the renderer is already gone (the title-stack restore on destroy — at that
|
||||
* point there is no frame left to tear). */
|
||||
function writeRaw(seam: RendererSeam, chunk: string, options?: { evenIfDestroyed?: boolean }): void {
|
||||
try {
|
||||
if (!seam.isDestroyed) {
|
||||
seam.writeOut(chunk)
|
||||
return
|
||||
}
|
||||
if (options?.evenIfDestroyed) process.stdout.write(chunk)
|
||||
} catch (cause) {
|
||||
getLog().warn('chrome', 'control write failed', { cause: String(cause) })
|
||||
}
|
||||
}
|
||||
|
|
@ -30,10 +30,11 @@ import { GatewayService, type GatewayServiceShape } from '../boundary/gateway/Ga
|
|||
import { liveGatewayLayer } from '../boundary/gateway/liveGateway.ts'
|
||||
import { getLog } from '../boundary/log.ts'
|
||||
import { startMemlog } from '../boundary/memlog.ts'
|
||||
import { registerVendoredParsers } from '../boundary/parsers.ts'
|
||||
import { acquireRenderer } from '../boundary/renderer.ts'
|
||||
import { makeAppLayer } from '../boundary/runtime.ts'
|
||||
import { nthAssistantResponse } from '../logic/copy.ts'
|
||||
import { envFlag } from '../logic/env.ts'
|
||||
import { envFlag, launchCwd } from '../logic/env.ts'
|
||||
import { createPromptHistory, dirHistoryPersister, loadDirHistory } from '../logic/history.ts'
|
||||
import { createPasteStore } from '../logic/pastes.ts'
|
||||
import { mapResumeHistory } from '../logic/resume.ts'
|
||||
|
|
@ -48,6 +49,12 @@ import {
|
|||
} from '../logic/slash.ts'
|
||||
import { createSessionStore, type SessionStore } from '../logic/store.ts'
|
||||
import { App } from '../view/App.tsx'
|
||||
import { TerminalChrome } from '../view/terminalChrome.tsx'
|
||||
|
||||
// Syntax-highlighting language expansion: register the vendored tree-sitter
|
||||
// grammars (python/rust/go/bash/json/c/html/css/yaml/toml) before the first
|
||||
// <code>/<markdown> mount initializes the global tree-sitter client.
|
||||
registerVendoredParsers()
|
||||
import type { SessionPickerOps } from '../view/overlays/sessionPicker.tsx'
|
||||
import { ThemeProvider } from '../view/theme.tsx'
|
||||
import { makeFakeGatewayLayer, type FakeGatewayController } from './fakeGateway.ts'
|
||||
|
|
@ -174,7 +181,18 @@ const postSessionSetup = (gateway: GatewayServiceShape, store: SessionStore, sid
|
|||
const createFreshSession = (gateway: GatewayServiceShape, store: SessionStore, input: TuiInput) =>
|
||||
Effect.gen(function* () {
|
||||
const created = yield* gateway.request<{ session_id?: string; info?: Record<string, unknown> }>('session.create', {
|
||||
cols: input.cols
|
||||
cols: input.cols,
|
||||
// The launch directory IS the workspace choice in a terminal (you cd'd
|
||||
// here) — passing it makes the gateway treat it as explicit, so the
|
||||
// session row gets a persisted cwd on first message, the chrome bar shows
|
||||
// the right dir, and /sessions groups this directory's sessions first.
|
||||
// NOT process.cwd(): the hermes launcher runs this engine with cwd set to
|
||||
// its own package dir (ui-opentui), so process.cwd() would be the engine
|
||||
// dir. The launcher exports the REAL launch dir as HERMES_CWD / the
|
||||
// gateway's TERMINAL_CWD; prefer those, falling back to process.cwd()
|
||||
// only when launched standalone (smokes/dev). (Desktop omits cwd — its
|
||||
// launch dir is meaningless; see _ensure_session_db_row.)
|
||||
cwd: launchCwd()
|
||||
})
|
||||
const sid = created?.session_id ?? gateway.sessionId()
|
||||
if (!sid) {
|
||||
|
|
@ -542,6 +560,7 @@ export const run = Effect.fn('Tui.run')(function* (input: TuiInput) {
|
|||
() => (
|
||||
<KeymapProvider keymap={keymap}>
|
||||
<ThemeProvider theme={() => store.state.theme}>
|
||||
<TerminalChrome store={store} />
|
||||
<App
|
||||
store={store}
|
||||
onSubmit={submit}
|
||||
|
|
|
|||
|
|
@ -76,3 +76,28 @@ export function envComposerRows(value: string | undefined): number {
|
|||
export function envOutputUnlimited(value: string | undefined): boolean {
|
||||
return envOutputLines(value) === Number.POSITIVE_INFINITY
|
||||
}
|
||||
|
||||
/**
|
||||
* The session's launch directory for `session.create`'s `cwd` param.
|
||||
*
|
||||
* The hermes launcher runs the OpenTUI engine with its process cwd set to the
|
||||
* engine's own package dir, so `process.cwd()` is NOT where the user ran
|
||||
* hermes. The launcher exports the real launch dir as `HERMES_CWD` (and the
|
||||
* gateway's `TERMINAL_CWD`); prefer those. Falls back to `process.cwd()` only
|
||||
* for standalone launches (smokes/dev) where no launcher set them, and returns
|
||||
* `undefined` when even that is empty so the gateway resolves its own default.
|
||||
*/
|
||||
export function launchCwd(env: { readonly [k: string]: string | undefined } = process.env): string | undefined {
|
||||
// First NON-BLANK of the launcher's vars (?? would keep a blank HERMES_CWD
|
||||
// and never reach TERMINAL_CWD).
|
||||
for (const value of [env.HERMES_CWD, env.TERMINAL_CWD]) {
|
||||
const trimmed = (value ?? '').trim()
|
||||
if (trimmed) return trimmed
|
||||
}
|
||||
try {
|
||||
const cwd = process.cwd().trim()
|
||||
return cwd || undefined
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,6 +163,36 @@ export function filterSessions(query: string, rows: readonly SessionRow[]): Sess
|
|||
return fuzzyFilter(query, rows, sessionFields)
|
||||
}
|
||||
|
||||
// ── this-directory grouping ───────────────────────────────────────────────
|
||||
|
||||
/** Path equality for cwd grouping: trim + drop trailing slashes. Pure string
|
||||
* work (no fs) — rows carry the gateway's already-absolute paths. */
|
||||
export function normalizeCwd(path: string | undefined): string {
|
||||
return (path ?? '').trim().replace(/\/+$/, '')
|
||||
}
|
||||
|
||||
/** Display order with sessions started in the CURRENT directory first.
|
||||
*
|
||||
* Browse mode only: while a search query is active the fuzzy score owns the
|
||||
* order (relevance beats locality), so `hereCount` is 0 and rows pass through.
|
||||
* Stable within both groups (each keeps the gateway's recency order). The
|
||||
* view renders section captions off `hereCount`; selection math is untouched
|
||||
* because this just reorders the one flat list.
|
||||
*/
|
||||
export function orderRowsForCwd(
|
||||
rows: SessionRow[],
|
||||
currentCwd: string | undefined,
|
||||
query: string
|
||||
): { rows: SessionRow[]; hereCount: number } {
|
||||
const here = normalizeCwd(currentCwd)
|
||||
if (!here || query.trim()) return { hereCount: 0, rows }
|
||||
const local: SessionRow[] = []
|
||||
const elsewhere: SessionRow[] = []
|
||||
for (const row of rows) (normalizeCwd(row.cwd) === here ? local : elsewhere).push(row)
|
||||
if (!local.length) return { hereCount: 0, rows }
|
||||
return { hereCount: local.length, rows: [...local, ...elsewhere] }
|
||||
}
|
||||
|
||||
// ── key routing (pattern: completionMenu.ts routeMenuKey) ────────────────
|
||||
|
||||
export interface SessionPickerKeyContext {
|
||||
|
|
|
|||
|
|
@ -181,6 +181,9 @@ export interface SessionInfo {
|
|||
fast?: boolean
|
||||
cwd?: string
|
||||
branch?: string
|
||||
/** Session title (auto-titled after the first exchange / renamed via the
|
||||
* picker) — drives the terminal window-title chrome; unset until titled. */
|
||||
title?: string
|
||||
running?: boolean
|
||||
contextUsed?: number
|
||||
contextMax?: number
|
||||
|
|
@ -324,6 +327,7 @@ function infoPatchFrom(d: SessionInfoPatchDecoded): Partial<SessionInfo> {
|
|||
if (d.fast !== undefined) patch.fast = d.fast
|
||||
if (d.cwd) patch.cwd = d.cwd
|
||||
if (d.branch) patch.branch = d.branch
|
||||
if (d.title) patch.title = d.title
|
||||
if (d.running !== undefined) patch.running = d.running
|
||||
// prefer the nested usage.context_* numbers, else the top-level fallback.
|
||||
const used = d.usage?.context_used ?? d.context_used
|
||||
|
|
|
|||
105
ui-opentui/src/logic/termChrome.ts
Normal file
105
ui-opentui/src/logic/termChrome.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* Terminal chrome logic — window-title text and desktop-notification OSC
|
||||
* sequences. Pure string work (no OpenTUI imports); the boundary shim
|
||||
* (`boundary/termChrome.ts`) owns the renderer writes and focus tracking.
|
||||
*
|
||||
* Title: OSC 0/2 content is set natively via `renderer.setTerminalTitle`
|
||||
* (the zig side emits the escape) — this module only SHAPES the text:
|
||||
* `"{session title} — Hermes"` once the gateway titles the session,
|
||||
* `"Hermes Agent"` until then.
|
||||
*
|
||||
* Notifications: emitted when the TUI starts waiting on the user (blocking
|
||||
* prompt, turn complete). Three dialects, terminals ignore what they don't
|
||||
* speak:
|
||||
* OSC 9 `ESC ] 9 ; message BEL` (iTerm2 / ConEmu / wezterm)
|
||||
* OSC 99 `ESC ] 99 ; i=hermes ; title ST` (kitty desktop-notification
|
||||
* protocol — `p` defaults to title, `d` defaults to done)
|
||||
* OSC 777 `ESC ] 777 ; notify ; title ; body BEL` (urxvt / foot)
|
||||
*/
|
||||
|
||||
const ESC = '\u001b'
|
||||
const BEL = '\u0007'
|
||||
const ST = `${ESC}\\`
|
||||
|
||||
/** Strip control chars (C0/C1, incl. ESC/BEL) so user text can never
|
||||
* terminate or splice an escape sequence; collapse runs of whitespace;
|
||||
* cap the length. */
|
||||
export function sanitizeOscText(text: string, max = 120): string {
|
||||
const clean = (text ?? '')
|
||||
// eslint-disable-next-line no-control-regex
|
||||
.replace(/[\u0000-\u001f\u007f-\u009f]/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
return clean.length > max ? clean.slice(0, Math.max(1, max - 1)) + '…' : clean
|
||||
}
|
||||
|
||||
/** The window-title string: session title when known, Ink-era generic otherwise. */
|
||||
export function windowTitleFor(sessionTitle: string | undefined): string {
|
||||
const title = sanitizeOscText(sessionTitle ?? '', 80)
|
||||
return title ? `${title} — Hermes` : 'Hermes Agent'
|
||||
}
|
||||
|
||||
/** A notification's two text parts (body optional). */
|
||||
export interface TermNotification {
|
||||
readonly title: string
|
||||
readonly body?: string
|
||||
}
|
||||
|
||||
/** The raw escape sequences announcing `n` to the hosting terminal. OSC 9 and
|
||||
* 777 conventionally terminate with BEL; kitty's OSC 99 spec uses ST.
|
||||
* Semicolons are swapped out of the OSC 777 fields (its field separator). */
|
||||
export function notifySequences(n: TermNotification): string[] {
|
||||
const title = sanitizeOscText(n.title)
|
||||
const body = sanitizeOscText(n.body ?? '')
|
||||
if (!title) return []
|
||||
const combined = body ? `${title}: ${body}` : title
|
||||
const f777 = (s: string) => s.replace(/;/g, ',')
|
||||
return [
|
||||
`${ESC}]9;${combined}${BEL}`,
|
||||
`${ESC}]99;i=hermes;${combined}${ST}`,
|
||||
`${ESC}]777;notify;${f777(title)};${f777(body || title)}${BEL}`
|
||||
]
|
||||
}
|
||||
|
||||
/** The XTWINOPS title-stack pushes/pops bracketing our title ownership: save
|
||||
* the user's title on install, restore it on teardown (terminals without the
|
||||
* stack ignore these — they just keep our last title, same as today). */
|
||||
export const TITLE_STACK_SAVE = `${ESC}[22;0t`
|
||||
export const TITLE_STACK_RESTORE = `${ESC}[23;0t`
|
||||
|
||||
/** What to announce for a blocking prompt, by kind. Kinds arrive from the
|
||||
* store's ActivePrompt union; unknown kinds get the generic line so a new
|
||||
* prompt type can never silently drop notifications. */
|
||||
export function promptNotification(kind: string): TermNotification {
|
||||
switch (kind) {
|
||||
case 'clarify':
|
||||
return { title: 'Hermes', body: 'needs an answer to continue' }
|
||||
case 'approval':
|
||||
return { title: 'Hermes', body: 'wants approval to run a command' }
|
||||
case 'sudo':
|
||||
return { title: 'Hermes', body: 'needs your sudo password' }
|
||||
case 'secret':
|
||||
return { title: 'Hermes', body: 'needs a secret/API key' }
|
||||
case 'confirm':
|
||||
return { title: 'Hermes', body: 'is asking you to confirm' }
|
||||
default:
|
||||
return { title: 'Hermes', body: 'is waiting for your input' }
|
||||
}
|
||||
}
|
||||
|
||||
/** Turn-complete announcement. */
|
||||
export const TURN_COMPLETE_NOTIFICATION: TermNotification = {
|
||||
title: 'Hermes',
|
||||
body: 'finished — awaiting your input'
|
||||
}
|
||||
|
||||
/**
|
||||
* `HERMES_TUI_NOTIFY` kill-switch (TUI-only env var, same family as
|
||||
* HERMES_TUI_TOOL_OUTPUT_LINES): unset/anything-else = on, `0`/`false`/`off`
|
||||
* = no notification sequences are ever written. The window title is NOT
|
||||
* gated by this — it's chrome, not interruption.
|
||||
*/
|
||||
export function notifyEnabled(env: { readonly [k: string]: string | undefined } = process.env): boolean {
|
||||
const raw = (env.HERMES_TUI_NOTIFY ?? '').trim().toLowerCase()
|
||||
return raw !== '0' && raw !== 'false' && raw !== 'off'
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { envFlag, envOutputLines, envOutputUnlimited } from '../logic/env.ts'
|
||||
import { envFlag, envOutputLines, envOutputUnlimited, launchCwd } from '../logic/env.ts'
|
||||
|
||||
describe('envFlag', () => {
|
||||
test('recognizes truthy values regardless of case/whitespace', () => {
|
||||
|
|
@ -66,3 +66,18 @@ describe('envOutputLines (HERMES_TUI_TOOL_OUTPUT_LINES)', () => {
|
|||
expect(envOutputUnlimited('200')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('launchCwd (session.create cwd)', () => {
|
||||
test('prefers HERMES_CWD (real launch dir the hermes launcher exports)', () => {
|
||||
expect(launchCwd({ HERMES_CWD: '/home/u/proj', TERMINAL_CWD: '/other' })).toBe('/home/u/proj')
|
||||
})
|
||||
|
||||
test('falls back to TERMINAL_CWD when HERMES_CWD is unset/blank', () => {
|
||||
expect(launchCwd({ TERMINAL_CWD: '/home/u/wt' })).toBe('/home/u/wt')
|
||||
expect(launchCwd({ HERMES_CWD: ' ', TERMINAL_CWD: '/home/u/wt' })).toBe('/home/u/wt')
|
||||
})
|
||||
|
||||
test('falls back to process.cwd() (non-empty) when no launcher env set', () => {
|
||||
expect(launchCwd({})).toBe(process.cwd())
|
||||
})
|
||||
})
|
||||
|
|
|
|||
74
ui-opentui/src/test/parsers.test.tsx
Normal file
74
ui-opentui/src/test/parsers.test.tsx
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Vendored tree-sitter grammar registration (syntax-highlighting language
|
||||
* expansion). Layers:
|
||||
* 1. config: every manifest grammar has valid vendored assets (wasm magic,
|
||||
* non-empty query) and the built configs point at existing absolute paths.
|
||||
* 2. resolution: core's filetype maps route our curated extensions/fence
|
||||
* labels to the registered filetype ids.
|
||||
* Visual color is live-smoke territory (highlighting settles async — see
|
||||
* codeBlock.tsx); these tests pin the wiring that makes it possible.
|
||||
*/
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { isAbsolute } from 'node:path'
|
||||
|
||||
import { extToFiletype, infoStringToFiletype, pathToFiletype } from '@opentui/core'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { registerVendoredParsers, vendoredParsers } from '../boundary/parsers.ts'
|
||||
|
||||
const EXPECTED = ['python', 'rust', 'go', 'bash', 'json', 'c', 'html', 'css', 'yaml', 'toml']
|
||||
|
||||
describe('vendored grammar configs', () => {
|
||||
test('all 10 curated grammars resolve with existing absolute asset paths', () => {
|
||||
const configs = vendoredParsers()
|
||||
expect(configs.map(c => c.filetype).sort()).toEqual([...EXPECTED].sort())
|
||||
for (const config of configs) {
|
||||
expect(isAbsolute(config.wasm)).toBe(true)
|
||||
expect(isAbsolute(config.queries.highlights[0]!)).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
test('vendored wasm files carry the wasm magic; queries are non-empty', () => {
|
||||
for (const config of vendoredParsers()) {
|
||||
const wasm = readFileSync(config.wasm)
|
||||
expect(wasm.subarray(0, 4).toString('latin1'), config.filetype).toBe('\0asm')
|
||||
const query = readFileSync(config.queries.highlights[0]!, 'utf8')
|
||||
expect(query.trim().length, config.filetype).toBeGreaterThan(0)
|
||||
}
|
||||
})
|
||||
|
||||
test('registerVendoredParsers registers and reports the full set', () => {
|
||||
const registered = registerVendoredParsers()
|
||||
expect(registered.map(r => r.filetype).sort()).toEqual([...EXPECTED].sort())
|
||||
})
|
||||
|
||||
test('a missing assets dir degrades to empty (plain-text fallback), no throw', () => {
|
||||
expect(vendoredParsers('/nonexistent/parsers')).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('filetype routing into the registered ids', () => {
|
||||
test('tool-body path extensions resolve to curated filetypes', () => {
|
||||
expect(pathToFiletype('a/b/script.py')).toBe('python')
|
||||
expect(pathToFiletype('src/main.rs')).toBe('rust')
|
||||
expect(pathToFiletype('cmd/main.go')).toBe('go')
|
||||
expect(pathToFiletype('run.sh')).toBe('bash')
|
||||
expect(pathToFiletype('conf.yaml')).toBe('yaml')
|
||||
expect(pathToFiletype('conf.yml')).toBe('yaml')
|
||||
expect(pathToFiletype('Cargo.toml')).toBe('toml')
|
||||
expect(pathToFiletype('lib.c')).toBe('c')
|
||||
expect(pathToFiletype('lib.h')).toBe('c')
|
||||
expect(pathToFiletype('index.html')).toBe('html')
|
||||
expect(pathToFiletype('style.css')).toBe('css')
|
||||
expect(pathToFiletype('package.json')).toBe('json')
|
||||
})
|
||||
|
||||
test('markdown fence labels resolve to curated filetypes (3b — injections)', () => {
|
||||
expect(infoStringToFiletype('python')).toBe('python')
|
||||
expect(infoStringToFiletype('py')).toBe('python')
|
||||
expect(infoStringToFiletype('rust')).toBe('rust')
|
||||
expect(infoStringToFiletype('sh')).toBe('bash')
|
||||
expect(infoStringToFiletype('yaml title=x.yml')).toBe('yaml')
|
||||
expect(extToFiletype('zsh')).toBe('bash')
|
||||
})
|
||||
})
|
||||
|
|
@ -22,7 +22,9 @@ import {
|
|||
SESSION_TABS,
|
||||
tabAccepts,
|
||||
tailTruncate,
|
||||
type SessionRow
|
||||
type SessionRow,
|
||||
normalizeCwd,
|
||||
orderRowsForCwd
|
||||
} from '../logic/sessionPicker.ts'
|
||||
|
||||
const row = (over: Partial<SessionRow>): SessionRow => ({
|
||||
|
|
@ -254,3 +256,28 @@ describe('slash entry points', () => {
|
|||
expect(resolveSessionArg(rows, '')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('orderRowsForCwd — pure edges', () => {
|
||||
const row = (id: string, cwd?: string) =>
|
||||
({ cwd, id, lastActive: 0, messageCount: 0, preview: '', source: 'tui', startedAt: 0, title: id }) as never
|
||||
|
||||
test('normalizeCwd trims and strips trailing slashes; empty-safe', () => {
|
||||
expect(normalizeCwd(' /a/b// ')).toBe('/a/b')
|
||||
expect(normalizeCwd(undefined)).toBe('')
|
||||
expect(normalizeCwd(' ')).toBe('')
|
||||
})
|
||||
|
||||
test('identity passthrough when nothing matches or no cwd known', () => {
|
||||
const rows = [row('a', '/x'), row('b')]
|
||||
expect(orderRowsForCwd(rows, undefined, '')).toEqual({ hereCount: 0, rows })
|
||||
expect(orderRowsForCwd(rows, '/nowhere', '')).toEqual({ hereCount: 0, rows })
|
||||
expect(orderRowsForCwd(rows, '/x', 'query')).toEqual({ hereCount: 0, rows })
|
||||
})
|
||||
|
||||
test('stable partition: here first, recency kept within groups', () => {
|
||||
const rows = [row('a', '/y'), row('b', '/x'), row('c'), row('d', '/x/')]
|
||||
const out = orderRowsForCwd(rows, '/x', '')
|
||||
expect(out.hereCount).toBe(2)
|
||||
expect(out.rows.map(r => (r as { id: string }).id)).toEqual(['b', 'd', 'a', 'c'])
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ interface MountOptions {
|
|||
sessions?: FakeSession[]
|
||||
truncated?: boolean
|
||||
initialTab?: 'recent' | 'cron' | 'gateways' | 'all'
|
||||
/** The TUI's cwd — drives the this-directory-first grouping. */
|
||||
currentCwd?: string
|
||||
/** Per-id peek delay (ms) — drives the stale-cancellation test. */
|
||||
peekDelay?: (id: string) => number
|
||||
/** Paged list: serve `sessions` windowed by offset/limit instead of whole. */
|
||||
|
|
@ -118,6 +120,7 @@ async function mountPicker(options: MountOptions = {}): Promise<Harness> {
|
|||
<SessionPicker
|
||||
ops={ops}
|
||||
initialTab={options.initialTab ?? 'recent'}
|
||||
currentCwd={() => options.currentCwd}
|
||||
peekDebounceMs={20}
|
||||
onResume={id => resumed.push(id)}
|
||||
onClose={() => (closed.value = true)}
|
||||
|
|
@ -356,3 +359,65 @@ describe('SessionPicker — pagination', () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('this-directory grouping', () => {
|
||||
const CWD = '/home/u/projects/alpha'
|
||||
const GROUPED: FakeSession[] = [
|
||||
{ cwd: '/elsewhere/beta', id: 'g1', last_active: NOW_S - 60, message_count: 5, source: 'tui', title: 'beta work' },
|
||||
{ cwd: CWD, id: 'g2', last_active: NOW_S - 120, message_count: 8, source: 'tui', title: 'alpha here' },
|
||||
{ id: 'g3', last_active: NOW_S - 180, message_count: 2, source: 'cli', title: 'no cwd at all' },
|
||||
{
|
||||
cwd: CWD + '/',
|
||||
id: 'g4',
|
||||
last_active: NOW_S - 240,
|
||||
message_count: 4,
|
||||
source: 'tui',
|
||||
title: 'alpha trailing slash'
|
||||
}
|
||||
]
|
||||
|
||||
test('sessions started in the current cwd group first under a caption', async () => {
|
||||
const h = await mountPicker({ currentCwd: CWD, sessions: GROUPED })
|
||||
try {
|
||||
const frame = h.probe.frame()
|
||||
const at = (needle: string) => frame.indexOf(needle)
|
||||
expect(at('▾ this directory (2)')).toBeGreaterThanOrEqual(0)
|
||||
expect(at('▾ other directories')).toBeGreaterThan(at('▾ this directory (2)'))
|
||||
// here-rows (incl. trailing-slash normalization) above the caption split,
|
||||
// elsewhere rows below it; selection starts on the first here-row.
|
||||
expect(at('alpha here')).toBeLessThan(at('▾ other directories'))
|
||||
expect(at('alpha trailing slash')).toBeLessThan(at('▾ other directories'))
|
||||
expect(at('beta work')).toBeGreaterThan(at('▾ other directories'))
|
||||
expect(at('no cwd at all')).toBeGreaterThan(at('▾ other directories'))
|
||||
expect(frame).toContain('❯ alpha here')
|
||||
// Enter resumes the first here-session
|
||||
h.probe.keys.pressEnter()
|
||||
await h.probe.settle()
|
||||
expect(h.resumed).toEqual(['g2'])
|
||||
} finally {
|
||||
h.probe.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test('search drops the grouping (fuzzy relevance owns the order)', async () => {
|
||||
const h = await mountPicker({ currentCwd: CWD, sessions: GROUPED })
|
||||
try {
|
||||
await h.probe.keys.typeText('beta')
|
||||
await h.probe.settle()
|
||||
const frame = await h.probe.waitForFrame(f => f.includes('beta work'))
|
||||
expect(frame).not.toContain('▾ this directory')
|
||||
expect(frame).not.toContain('▾ other directories')
|
||||
} finally {
|
||||
h.probe.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test('no current cwd (or no matches) → plain recency list, no captions', async () => {
|
||||
const h = await mountPicker({ sessions: GROUPED })
|
||||
try {
|
||||
expect(h.probe.frame()).not.toContain('▾ this directory')
|
||||
} finally {
|
||||
h.probe.destroy()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
149
ui-opentui/src/test/termChrome.test.tsx
Normal file
149
ui-opentui/src/test/termChrome.test.tsx
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* Terminal chrome: OSC 0/2 window title + OSC 9/99/777 waiting-on-you
|
||||
* notifications. Layers:
|
||||
* 1. pure: title shaping, OSC sanitization, the three notification
|
||||
* dialect sequences, the prompt-kind copy, the env kill-switch
|
||||
* (logic/termChrome.ts).
|
||||
* 2. wiring: <TerminalChrome> with an injected fake seam over a real
|
||||
* store — the title tracks session.info, prompts and turn-completion
|
||||
* edges notify exactly once, initial state stays silent.
|
||||
*/
|
||||
import { createRoot } from 'solid-js'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import type { TerminalChromeSeam } from '../boundary/termChrome.ts'
|
||||
import { createSessionStore } from '../logic/store.ts'
|
||||
import {
|
||||
notifyEnabled,
|
||||
notifySequences,
|
||||
promptNotification,
|
||||
sanitizeOscText,
|
||||
TURN_COMPLETE_NOTIFICATION,
|
||||
windowTitleFor
|
||||
} from '../logic/termChrome.ts'
|
||||
import { TerminalChrome } from '../view/terminalChrome.tsx'
|
||||
|
||||
const ESC = '\u001b'
|
||||
const BEL = '\u0007'
|
||||
|
||||
describe('windowTitleFor — title shaping', () => {
|
||||
test('generic until the session is titled', () => {
|
||||
expect(windowTitleFor(undefined)).toBe('Hermes Agent')
|
||||
expect(windowTitleFor('')).toBe('Hermes Agent')
|
||||
expect(windowTitleFor(' ')).toBe('Hermes Agent')
|
||||
})
|
||||
|
||||
test('session title gets the — Hermes suffix', () => {
|
||||
expect(windowTitleFor('fix the flaky tests')).toBe('fix the flaky tests — Hermes')
|
||||
})
|
||||
|
||||
test('long titles are capped', () => {
|
||||
const long = 'x'.repeat(200)
|
||||
expect(windowTitleFor(long).length).toBeLessThanOrEqual(80 + ' — Hermes'.length)
|
||||
expect(windowTitleFor(long)).toContain('…')
|
||||
})
|
||||
})
|
||||
|
||||
describe('sanitizeOscText — escape-splice safety', () => {
|
||||
test('control chars (incl. ESC/BEL) can never splice a sequence', () => {
|
||||
expect(sanitizeOscText(`evil${ESC}]0;pwned${BEL}title`)).toBe('evil ]0;pwned title')
|
||||
})
|
||||
|
||||
test('whitespace collapses; ends trimmed', () => {
|
||||
expect(sanitizeOscText(' a\n\tb ')).toBe('a b')
|
||||
})
|
||||
})
|
||||
|
||||
describe('notifySequences — the three dialects', () => {
|
||||
test('emits OSC 9, kitty OSC 99, and OSC 777', () => {
|
||||
const [osc9, osc99, osc777] = notifySequences({ title: 'Hermes', body: 'finished' })
|
||||
expect(osc9).toBe(`${ESC}]9;Hermes: finished${BEL}`)
|
||||
expect(osc99).toBe(`${ESC}]99;i=hermes;Hermes: finished${ESC}\\`)
|
||||
expect(osc777).toBe(`${ESC}]777;notify;Hermes;finished${BEL}`)
|
||||
})
|
||||
|
||||
test('semicolons cannot splice OSC 777 fields', () => {
|
||||
const [, , osc777] = notifySequences({ title: 'a;b', body: 'c;d' })
|
||||
expect(osc777).toBe(`${ESC}]777;notify;a,b;c,d${BEL}`)
|
||||
})
|
||||
|
||||
test('an empty title produces nothing', () => {
|
||||
expect(notifySequences({ title: ' ' })).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('promptNotification + env gate', () => {
|
||||
test('every known prompt kind has copy; unknown kinds fall back', () => {
|
||||
for (const kind of ['clarify', 'approval', 'sudo', 'secret', 'confirm', 'someday-new']) {
|
||||
const n = promptNotification(kind)
|
||||
expect(n.title).toBe('Hermes')
|
||||
expect(n.body).toBeTruthy()
|
||||
}
|
||||
expect(promptNotification('someday-new').body).toBe('is waiting for your input')
|
||||
})
|
||||
|
||||
test('HERMES_TUI_NOTIFY=0/false/off disables; default on', () => {
|
||||
expect(notifyEnabled({})).toBe(true)
|
||||
expect(notifyEnabled({ HERMES_TUI_NOTIFY: '1' })).toBe(true)
|
||||
expect(notifyEnabled({ HERMES_TUI_NOTIFY: '0' })).toBe(false)
|
||||
expect(notifyEnabled({ HERMES_TUI_NOTIFY: 'false' })).toBe(false)
|
||||
expect(notifyEnabled({ HERMES_TUI_NOTIFY: 'off' })).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('<TerminalChrome> wiring — store edges drive the seam', () => {
|
||||
function mount() {
|
||||
const store = createSessionStore()
|
||||
const titles: Array<string | undefined> = []
|
||||
const notifications: string[] = []
|
||||
const seam: TerminalChromeSeam = {
|
||||
setTitle: t => titles.push(t),
|
||||
notify: n => notifications.push(n.body ?? n.title)
|
||||
}
|
||||
const dispose = createRoot(d => {
|
||||
TerminalChrome({ chrome: seam, store })
|
||||
return d
|
||||
})
|
||||
return { dispose, notifications, store, titles }
|
||||
}
|
||||
|
||||
test('sets the generic title immediately, then tracks session.info title', () => {
|
||||
const { dispose, store, titles } = mount()
|
||||
try {
|
||||
expect(titles).toEqual([undefined]) // boot → windowTitleFor(undefined) inside the seam
|
||||
store.apply({ type: 'session.info', payload: { title: 'rename the moon' } })
|
||||
expect(titles).toEqual([undefined, 'rename the moon'])
|
||||
} finally {
|
||||
dispose()
|
||||
}
|
||||
})
|
||||
|
||||
test('a blocking prompt notifies once; initial state is silent', () => {
|
||||
const { dispose, notifications, store } = mount()
|
||||
try {
|
||||
expect(notifications).toEqual([])
|
||||
store.apply({
|
||||
type: 'clarify.request',
|
||||
payload: { choices: null, question: 'which one?', request_id: 'r1' }
|
||||
})
|
||||
expect(notifications).toEqual(['needs an answer to continue'])
|
||||
// clearing the prompt does not notify again
|
||||
store.clearPrompt()
|
||||
expect(notifications).toEqual(['needs an answer to continue'])
|
||||
} finally {
|
||||
dispose()
|
||||
}
|
||||
})
|
||||
|
||||
test('turn completion (running true→false) notifies; boot idle does not', () => {
|
||||
const { dispose, notifications, store } = mount()
|
||||
try {
|
||||
store.apply({ type: 'message.start' })
|
||||
expect(notifications).toEqual([])
|
||||
store.apply({ type: 'message.complete', payload: { text: 'done' } })
|
||||
expect(notifications).toEqual([TURN_COMPLETE_NOTIFICATION.body])
|
||||
} finally {
|
||||
dispose()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
@ -156,6 +156,7 @@ export function App(props: AppProps) {
|
|||
<SessionPicker
|
||||
ops={props.sessionOps ?? NOOP_OPS}
|
||||
initialTab={sp().tab}
|
||||
currentCwd={() => props.store.state.info.cwd}
|
||||
onResume={resume}
|
||||
onClose={closeSessionPicker}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import { visibleRows, type PickerRow } from '../../logic/fuzzy.ts'
|
|||
import {
|
||||
filterSessions,
|
||||
listParamsFor,
|
||||
orderRowsForCwd,
|
||||
mapSessionRows,
|
||||
relativeTime,
|
||||
routeSessionPickerKey,
|
||||
|
|
@ -79,6 +80,9 @@ export function SessionPicker(props: {
|
|||
onResume: (sessionId: string) => void
|
||||
onClose: () => void
|
||||
initialTab?: SessionTabId
|
||||
/** The TUI's working directory — sessions started here group first while
|
||||
* browsing (no effect during search). */
|
||||
currentCwd?: () => string | undefined
|
||||
/** Test seam: override the peek debounce (default PEEK_DEBOUNCE_MS). */
|
||||
peekDebounceMs?: number
|
||||
}) {
|
||||
|
|
@ -134,7 +138,12 @@ export function SessionPicker(props: {
|
|||
})
|
||||
)
|
||||
|
||||
const filtered = createMemo(() => filterSessions(query(), rows()))
|
||||
// Display order: this-directory sessions first while browsing (design ask
|
||||
// 2026-06-12); search keeps pure fuzzy relevance. One flat list, so the
|
||||
// selection/windowing math below is order-agnostic.
|
||||
const ordered = createMemo(() => orderRowsForCwd(filterSessions(query(), rows()), props.currentCwd?.(), query()))
|
||||
const filtered = createMemo(() => ordered().rows)
|
||||
const hereCount = createMemo(() => ordered().hereCount)
|
||||
createEffect(on(query, () => setSel(0), { defer: true }))
|
||||
|
||||
// "load more" pseudo-row: selectable index === filtered().length. Offered
|
||||
|
|
@ -371,6 +380,12 @@ export function SessionPicker(props: {
|
|||
{row =>
|
||||
row.kind === 'item' && row.item ? (
|
||||
<box style={{ flexDirection: 'column' }} onMouseDown={() => setSel(row.index)}>
|
||||
<Show when={hereCount() > 0 && row.index === 0}>
|
||||
<text fg={theme().color.muted}>{` ▾ this directory (${hereCount()})`}</text>
|
||||
</Show>
|
||||
<Show when={hereCount() > 0 && row.index === hereCount()}>
|
||||
<text fg={theme().color.muted}>{' ▾ other directories'}</text>
|
||||
</Show>
|
||||
<text bg={row.index === sel() ? theme().color.selectionBg : 'transparent'}>
|
||||
<span style={{ fg: row.index === sel() ? theme().color.text : theme().color.muted }}>
|
||||
{row.index === sel() ? '❯ ' : ' '}
|
||||
|
|
|
|||
61
ui-opentui/src/view/terminalChrome.tsx
Normal file
61
ui-opentui/src/view/terminalChrome.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* <TerminalChrome> — render-nothing wiring between store state and the
|
||||
* terminal-chrome seam (window title + waiting-on-you notifications).
|
||||
*
|
||||
* title: tracks `info.title` — "Hermes Agent" until the gateway titles
|
||||
* the session (first-exchange auto-title / picker rename), then
|
||||
* "{title} — Hermes". Runs immediately on mount so the generic
|
||||
* title is set at boot.
|
||||
* notify: fires on the EDGES the user must act on —
|
||||
* · a blocking prompt appearing (clarify/approval/sudo/secret/
|
||||
* confirm — `state.prompt` undefined → defined), and
|
||||
* · a turn finishing (`info.running` true → false).
|
||||
* Both deferred (no notification for the initial state) and
|
||||
* de-duplicated by the seam's focus gate.
|
||||
*
|
||||
* The seam is injectable for headless tests; production resolves it from
|
||||
* the live renderer via useRenderer().
|
||||
*/
|
||||
import { useRenderer } from '@opentui/solid'
|
||||
import { createEffect, on } from 'solid-js'
|
||||
|
||||
import { installTerminalChrome, type TerminalChromeSeam } from '../boundary/termChrome.ts'
|
||||
import type { createSessionStore } from '../logic/store.ts'
|
||||
import { promptNotification, TURN_COMPLETE_NOTIFICATION } from '../logic/termChrome.ts'
|
||||
|
||||
type Store = ReturnType<typeof createSessionStore>
|
||||
|
||||
export function TerminalChrome(props: { store: Store; chrome?: TerminalChromeSeam }) {
|
||||
// Injected seam (tests) skips useRenderer() — headless mounts have no
|
||||
// opentui context to read.
|
||||
const chrome = props.chrome ?? installTerminalChrome(useRenderer())
|
||||
|
||||
// Window title — immediate (sets the generic title at boot) and reactive.
|
||||
createEffect(() => {
|
||||
chrome.setTitle(props.store.state.info.title)
|
||||
})
|
||||
|
||||
// Blocking prompt appeared → the agent is waiting on the user.
|
||||
createEffect(
|
||||
on(
|
||||
() => props.store.state.prompt,
|
||||
(prompt, previous) => {
|
||||
if (prompt && !previous) chrome.notify(promptNotification(prompt.kind))
|
||||
},
|
||||
{ defer: true }
|
||||
)
|
||||
)
|
||||
|
||||
// Turn finished → control is back with the user.
|
||||
createEffect(
|
||||
on(
|
||||
() => props.store.state.info.running,
|
||||
(running, previous) => {
|
||||
if (previous === true && running === false) chrome.notify(TURN_COMPLETE_NOTIFICATION)
|
||||
},
|
||||
{ defer: true }
|
||||
)
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue