eval-harness 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,676 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import re
6
+ import urllib.parse
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ from .base import (
11
+ AgentRunner,
12
+ DEFAULT_ATTACHED_INSTRUCTION_PROMPT,
13
+ _command_get_named_arg,
14
+ _command_set_named_arg,
15
+ normalize_agent_value,
16
+ parse_log_key_values,
17
+ )
18
+
19
+
20
+ class MiMoCodeRunner(AgentRunner):
21
+ """MiMo Code CLI agent runner adapter."""
22
+
23
+ harness_agent_name = "harness-build"
24
+
25
+ @property
26
+ def name(self) -> str:
27
+ return "mimocode"
28
+
29
+ @property
30
+ def binary(self) -> str:
31
+ return "mimo"
32
+
33
+ @property
34
+ def config_key(self) -> str:
35
+ return "mimocode"
36
+
37
+ # -- command building
38
+
39
+ def default_command(self, config: dict[str, Any]) -> list[str]:
40
+ return [
41
+ "mimo",
42
+ "run",
43
+ *self.format_flags(),
44
+ "--dangerously-skip-permissions",
45
+ "--file={instruction}",
46
+ "--dir={workspace}",
47
+ "--agent",
48
+ self.harness_agent_name,
49
+ DEFAULT_ATTACHED_INSTRUCTION_PROMPT,
50
+ ]
51
+
52
+ def command_with_model(self, command: list[str], model: str) -> list[str]:
53
+ """Inject --model before MiMo's positional message argument."""
54
+ return _mimocode_set_option_before_message(command, "--model", model)
55
+
56
+ def command_with_variant(self, command: list[str], variant: str) -> list[str]:
57
+ """MiMo Code uses --agent instead of --variant."""
58
+ if not variant:
59
+ return command
60
+ if self._looks_like_reasoning_variant(variant):
61
+ return command
62
+ return _command_set_named_arg(command, "--agent", variant)
63
+
64
+ def variant_cli_flag(self) -> str:
65
+ return "--agent"
66
+
67
+ def variant_from_command(self, command: list[str]) -> str:
68
+ return _command_get_named_arg(command, "--agent")
69
+
70
+ # -- log directory
71
+
72
+ def log_dir_name(self) -> str:
73
+ return "mimocode"
74
+
75
+ # -- asset installation
76
+
77
+ def default_asset_installs(self) -> list[dict[str, Any]]:
78
+ return [
79
+ {
80
+ "source": "work/work/skills/*",
81
+ "target": ".mimocode/skills",
82
+ "kind": "skills",
83
+ "entries": "directories",
84
+ "required": False,
85
+ "clean": True,
86
+ },
87
+ {
88
+ "source": "work/work/skills/versions.json",
89
+ "target": ".mimocode/skills",
90
+ "kind": "skill-manifest",
91
+ "entries": "files",
92
+ "required": False,
93
+ "clean": False,
94
+ },
95
+ {
96
+ "source": "work/skills/*",
97
+ "target": ".mimocode/skills",
98
+ "kind": "skills-flat-fallback",
99
+ "entries": "directories",
100
+ "required": False,
101
+ "clean": False,
102
+ },
103
+ {
104
+ "source": "work/skills/versions.json",
105
+ "target": ".mimocode/skills",
106
+ "kind": "skill-manifest-flat-fallback",
107
+ "entries": "files",
108
+ "required": False,
109
+ "clean": False,
110
+ },
111
+ {
112
+ "source": "work/work/skills/*.md",
113
+ "target": ".mimocode/agents",
114
+ "kind": "agents",
115
+ "required": False,
116
+ "clean": True,
117
+ },
118
+ {
119
+ "source": "work/skills/*.md",
120
+ "target": ".mimocode/agents",
121
+ "kind": "agents-flat-fallback",
122
+ "required": False,
123
+ "clean": False,
124
+ },
125
+ ]
126
+
127
+ # -- runtime profile seeding
128
+
129
+ def runtime_profile_candidates(
130
+ self, base_env: dict[str, str], runtime: dict[str, str]
131
+ ) -> list[tuple[Path | None, Path, str]]:
132
+ from ..cli import existing_path
133
+
134
+ home = Path(runtime["home_dir"])
135
+ appdata = Path(runtime.get("appdata_dir", home / "AppData" / "Roaming"))
136
+ localappdata = Path(runtime.get("localappdata_dir", home / "AppData" / "Local"))
137
+ config_dir = Path(runtime["config_dir"])
138
+ data_dir = Path(runtime["data_dir"])
139
+
140
+ return [
141
+ (existing_path(base_env.get("USERPROFILE"), ".config", "mimocode"), config_dir / "mimocode", "USERPROFILE/.config/mimocode"),
142
+ (existing_path(base_env.get("USERPROFILE"), ".local", "share", "mimocode"), data_dir / "mimocode", "USERPROFILE/.local/share/mimocode"),
143
+ (existing_path(base_env.get("USERPROFILE"), ".cache", "mimocode"), Path(runtime["cache_dir"]) / "mimocode", "USERPROFILE/.cache/mimocode"),
144
+ (existing_path(base_env.get("USERPROFILE"), ".mimocode"), home / ".mimocode", "USERPROFILE/.mimocode"),
145
+ (existing_path(base_env.get("APPDATA"), "mimocode"), appdata / "mimocode", "APPDATA/mimocode"),
146
+ (existing_path(base_env.get("LOCALAPPDATA"), "mimocode"), localappdata / "mimocode", "LOCALAPPDATA/mimocode"),
147
+ (existing_path(base_env.get("XDG_CONFIG_HOME"), "mimocode"), config_dir / "mimocode", "XDG_CONFIG_HOME/mimocode"),
148
+ (existing_path(base_env.get("XDG_DATA_HOME"), "mimocode"), data_dir / "mimocode", "XDG_DATA_HOME/mimocode"),
149
+ ]
150
+
151
+ # -- provider config
152
+
153
+ def write_agent_config(self, manifest: dict[str, Any]) -> str | None:
154
+ runtime = manifest.get("runtime") or {}
155
+ config_dir = Path(runtime["config_dir"]) / "mimocode"
156
+ config_dir.mkdir(parents=True, exist_ok=True)
157
+ config_path = config_dir / "mimocode.jsonc"
158
+
159
+ from ..cli import execution_agent_provider, read_json, write_json
160
+
161
+ data: dict[str, Any] = {}
162
+ if config_path.exists():
163
+ try:
164
+ data = read_json(config_path)
165
+ except json.JSONDecodeError:
166
+ data = {}
167
+ data.setdefault("$schema", "https://mimo.xiaomi.com/config.json")
168
+ execution = manifest.get("execution", {})
169
+ active_model = _mimocode_active_model(execution)
170
+ if active_model:
171
+ data["model"] = active_model
172
+
173
+ agents = data.setdefault("agent", {})
174
+ if not isinstance(agents, dict):
175
+ raise RuntimeError("mimocode agent config must be a JSON object")
176
+ agents[self.harness_agent_name] = self._harness_agent_config(active_model)
177
+ if active_model:
178
+ build_agent = agents.get("build")
179
+ if not isinstance(build_agent, dict):
180
+ build_agent = {}
181
+ build_agent["model"] = active_model
182
+ agents["build"] = build_agent
183
+ providers = data.setdefault("provider", {})
184
+ if not isinstance(providers, dict):
185
+ raise RuntimeError("mimocode provider config must be a JSON object")
186
+
187
+ provider = execution_agent_provider(execution, self)
188
+ if not isinstance(provider, dict):
189
+ return str(config_path)
190
+
191
+ provider_id = str(provider.get("id", "agent-inspector"))
192
+ models = provider.get("models") or {}
193
+ if not isinstance(models, dict):
194
+ raise RuntimeError("execution.opencode_provider.models must be a JSON object")
195
+ providers[provider_id] = {
196
+ "npm": str(provider.get("npm", "@ai-sdk/openai-compatible")),
197
+ "name": str(provider.get("name", "Agent Inspector")),
198
+ "options": {
199
+ "baseURL": str(provider.get("baseURL", "http://127.0.0.1:25947/proxy")),
200
+ "apiKey": str(provider.get("apiKey", "")),
201
+ },
202
+ "models": models,
203
+ }
204
+ write_json(config_path, data)
205
+ return str(config_path)
206
+
207
+ @staticmethod
208
+ def _looks_like_reasoning_variant(value: str) -> bool:
209
+ return value.strip().lower() in {
210
+ "minimal",
211
+ "low",
212
+ "medium",
213
+ "high",
214
+ "max",
215
+ "maximum",
216
+ }
217
+
218
+ def _harness_agent_config(self, active_model: str = "") -> dict[str, Any]:
219
+ config: dict[str, Any] = {
220
+ "description": (
221
+ "Eval Harness non-interactive build agent. It mirrors MiMo Code's "
222
+ "build mode, but pre-approves external_directory access so Jenkins runs "
223
+ "do not block on permission prompts."
224
+ ),
225
+ "mode": "primary",
226
+ "permission": {
227
+ "read": "allow",
228
+ "edit": "allow",
229
+ "glob": "allow",
230
+ "grep": "allow",
231
+ "list": "allow",
232
+ "bash": "allow",
233
+ "task": "allow",
234
+ "external_directory": "allow",
235
+ "todowrite": "allow",
236
+ "question": "deny",
237
+ "webfetch": "allow",
238
+ "websearch": "allow",
239
+ "lsp": "allow",
240
+ "doom_loop": "allow",
241
+ "skill": "allow",
242
+ },
243
+ "tools": {
244
+ "invalid": True,
245
+ "question": True,
246
+ "bash": True,
247
+ "read": True,
248
+ "glob": True,
249
+ "grep": True,
250
+ "edit": True,
251
+ "write": True,
252
+ "notebook_edit": True,
253
+ "actor": True,
254
+ "webfetch": True,
255
+ "skill": True,
256
+ "change_directory": True,
257
+ "plan_exit": True,
258
+ "plan_enter": True,
259
+ "memory": True,
260
+ "history": True,
261
+ "task": True,
262
+ "workflow": True,
263
+ },
264
+ }
265
+ if active_model:
266
+ config["model"] = active_model
267
+ return config
268
+
269
+ # -- log parsing: sessions
270
+
271
+ def extract_sessions_from_text(
272
+ self, text: str, *, inspector_base_url: str = "http://127.0.0.1:25947"
273
+ ) -> dict[str, Any]:
274
+ from ..cli import (
275
+ OPENCODE_SESSION_SCHEMA,
276
+ dt,
277
+ plain_log_text,
278
+ utc_now_seconds_text,
279
+ )
280
+
281
+ records: dict[str, dict[str, Any]] = {}
282
+ order: list[str] = []
283
+ primary_session_id: str | None = None
284
+
285
+ def remember(session_id: str) -> dict[str, Any]:
286
+ if session_id not in records:
287
+ order.append(session_id)
288
+ return _ensure_session_record(records, session_id)
289
+
290
+ for raw_line in text.splitlines():
291
+ line = plain_log_text(raw_line).strip()
292
+ if not line:
293
+ continue
294
+ if line.startswith("{"):
295
+ try:
296
+ payload = json.loads(line)
297
+ except json.JSONDecodeError:
298
+ continue
299
+ if not isinstance(payload, dict):
300
+ continue
301
+ # MiMo Code JSON stream: sessionID / part.sessionID
302
+ session_id = normalize_agent_value(str(payload.get("sessionID") or ""))
303
+ part = payload.get("part")
304
+ if not session_id and isinstance(part, dict):
305
+ session_id = normalize_agent_value(str(part.get("sessionID") or ""))
306
+ # Also try MiMo-specific: turnID / session.id
307
+ if not session_id:
308
+ session_id = normalize_agent_value(str(payload.get("turnID") or ""))
309
+ if not session_id and isinstance(part, dict):
310
+ session_id = normalize_agent_value(str(part.get("turnID") or ""))
311
+ if not session_id:
312
+ continue
313
+ record = remember(session_id)
314
+ _update_session_seen(record, _session_timestamp_from_json(payload))
315
+ event_type = str(payload.get("type") or "")
316
+ if event_type in ("tool_use", "tool-result"):
317
+ record["tool_call_count"] = int(record.get("tool_call_count", 0)) + 1
318
+ elif event_type in ("text", "content_block_start", "content_block_delta"):
319
+ record["text_part_count"] = int(record.get("text_part_count", 0)) + 1
320
+ elif event_type == "error":
321
+ record["error_count"] = int(record.get("error_count", 0)) + 1
322
+ if isinstance(part, dict):
323
+ if part.get("type") in ("step-finish", "turn-finish", "done"):
324
+ record["step_count"] = int(record.get("step_count", 0)) + 1
325
+ tokens = part.get("tokens") or part.get("usage")
326
+ if isinstance(tokens, dict):
327
+ _apply_step_tokens(record, tokens)
328
+ if not record.get("agent"):
329
+ record["agent"] = normalize_agent_value(
330
+ str(part.get("agent") or part.get("name") or "")
331
+ )
332
+ if primary_session_id is None:
333
+ primary_session_id = session_id
334
+ continue
335
+
336
+ # key=value log lines (shared format)
337
+ values = parse_log_key_values(line)
338
+ timestamp = normalize_agent_value(values.get("timestamp"))
339
+ created_id = normalize_agent_value(values.get("id")) if "message=created" in line else None
340
+ stream_session_id = normalize_agent_value(values.get("session.id"))
341
+ session_id = created_id or stream_session_id
342
+ if not session_id:
343
+ continue
344
+ record = remember(session_id)
345
+ _update_session_seen(record, timestamp)
346
+ if created_id:
347
+ parent_id = normalize_agent_value(values.get("parentID"))
348
+ record["parent_id"] = parent_id
349
+ record["title"] = normalize_agent_value(values.get("title")) or record.get("title")
350
+ record["agent"] = normalize_agent_value(values.get("agent")) or record.get("agent")
351
+ model = normalize_agent_value(values.get("model"))
352
+ if model:
353
+ record["model"] = model
354
+ if parent_id is None and primary_session_id is None:
355
+ primary_session_id = session_id
356
+ if stream_session_id:
357
+ record["provider"] = (
358
+ normalize_agent_value(values.get("providerID"))
359
+ or normalize_agent_value(values.get("llm.provider"))
360
+ or record.get("provider")
361
+ )
362
+ record["model"] = (
363
+ normalize_agent_value(values.get("modelID"))
364
+ or normalize_agent_value(values.get("llm.model"))
365
+ or record.get("model")
366
+ )
367
+ record["agent"] = normalize_agent_value(values.get("agent")) or record.get("agent")
368
+ record["mode"] = normalize_agent_value(values.get("mode")) or record.get("mode")
369
+ if primary_session_id is None:
370
+ primary_session_id = session_id
371
+
372
+ sessions = [records[session_id] for session_id in order]
373
+ base = inspector_base_url.rstrip("/") or "http://127.0.0.1:25947"
374
+ for record in sessions:
375
+ record["inspector_url"] = f"{base}/?sessionId={urllib.parse.quote(str(record['session_id']))}"
376
+ if not primary_session_id and sessions:
377
+ primary_session_id = str(sessions[0]["session_id"])
378
+ return {
379
+ "schema": OPENCODE_SESSION_SCHEMA,
380
+ "generated_at": utc_now_seconds_text(),
381
+ "inspector_base_url": base,
382
+ "inspector_sessions_api": f"{base}/api/sessions",
383
+ "primary_session_id": primary_session_id,
384
+ "session_count": len(sessions),
385
+ "subagent_session_count": sum(1 for item in sessions if item.get("parent_id")),
386
+ "sessions": sessions,
387
+ }
388
+
389
+ def render_sessions_md(self, summary: dict[str, Any]) -> str:
390
+ from ..cli import md_artifact_external_link, md_cell
391
+
392
+ lines = [
393
+ f"# MiMo Code Sessions",
394
+ "",
395
+ f"- Generated at: {summary.get('generated_at')}",
396
+ f"- Inspector: {summary.get('inspector_base_url')}",
397
+ f"- Sessions API: {summary.get('inspector_sessions_api')}",
398
+ f"- Primary session: `{summary.get('primary_session_id') or ''}`",
399
+ f"- Session count: {summary.get('session_count', 0)}",
400
+ f"- Subagent session count: {summary.get('subagent_session_count', 0)}",
401
+ "",
402
+ "| session | parent | agent | mode | model | steps | tools | errors | inspector |",
403
+ "| --- | --- | --- | --- | --- | ---: | ---: | ---: | --- |",
404
+ ]
405
+ for item in summary.get("sessions", []) or []:
406
+ lines.append(
407
+ "| "
408
+ + " | ".join(
409
+ [
410
+ md_cell(item.get("session_id")),
411
+ md_cell(item.get("parent_id")),
412
+ md_cell(item.get("agent")),
413
+ md_cell(item.get("mode")),
414
+ md_cell(item.get("model")),
415
+ md_cell(item.get("step_count")),
416
+ md_cell(item.get("tool_call_count")),
417
+ md_cell(item.get("error_count")),
418
+ md_artifact_external_link(str(item.get("inspector_url") or ""), "open"),
419
+ ]
420
+ )
421
+ + " |"
422
+ )
423
+ if not summary.get("sessions"):
424
+ lines.append("| none | | | | | 0 | 0 | 0 | |")
425
+ if summary.get("inspector_backfill_status") and summary.get("inspector_backfill_status") != "SKIPPED":
426
+ lines.extend(
427
+ [
428
+ "",
429
+ "## Inspector Log Backfill",
430
+ "",
431
+ f"- Status: `{summary.get('inspector_backfill_status') or ''}`",
432
+ f"- Query mode: `{summary.get('inspector_log_query_mode') or ''}`",
433
+ f"- Logs URL: {md_artifact_external_link(str(summary.get('inspector_logs_url') or ''), 'open')}",
434
+ f"- Log count: {summary.get('inspector_log_count', 0)}",
435
+ f"- Preview count: {summary.get('inspector_log_preview_count', 0)} / {summary.get('inspector_log_preview_limit', 0)}",
436
+ ]
437
+ )
438
+ if summary.get("inspector_logs_artifact"):
439
+ lines.append(f"- Full log artifact: `{summary.get('inspector_logs_artifact')}`")
440
+ if summary.get("inspector_backfill_reason"):
441
+ lines.append(f"- Reason: {summary.get('inspector_backfill_reason')}")
442
+ inspector_logs = summary.get("inspector_logs") or []
443
+ if inspector_logs:
444
+ lines.extend(
445
+ [
446
+ "",
447
+ "| log | session | model | status | path | inspector |",
448
+ "| ---: | --- | --- | ---: | --- | --- |",
449
+ ]
450
+ )
451
+ for item in inspector_logs:
452
+ lines.append(
453
+ "| "
454
+ + " | ".join(
455
+ [
456
+ md_cell(item.get("id")),
457
+ md_cell(item.get("session_id")),
458
+ md_cell(item.get("model")),
459
+ md_cell(item.get("status")),
460
+ md_cell(item.get("path")),
461
+ md_artifact_external_link(str(item.get("inspector_url") or ""), "open"),
462
+ ]
463
+ )
464
+ + " |"
465
+ )
466
+ lines.append("")
467
+ return "\n".join(lines)
468
+
469
+ # -- log parsing: model
470
+
471
+ def model_from_log(self, run_dir: Path) -> str:
472
+ log_path = run_dir / self.log_dir_name() / "opencode.log"
473
+ if not log_path.exists():
474
+ return ""
475
+ from ..cli import read_trace_text
476
+
477
+ try:
478
+ text = read_trace_text(log_path)
479
+ except OSError:
480
+ return ""
481
+ command_match = re.search(r"^\$\s+.+?\s--model\s+(\S+)", text, re.MULTILINE)
482
+ if command_match:
483
+ return command_match.group(1)
484
+ stream_match = re.search(r"providerID=(\S+)\s+modelID=(\S+)", text)
485
+ if stream_match:
486
+ return f"{stream_match.group(1)}/{stream_match.group(2)}"
487
+ runtime_match = re.search(r"llm\.provider=(\S+)\s+llm\.model=(\S+)", text)
488
+ if runtime_match:
489
+ return f"{runtime_match.group(1)}/{runtime_match.group(2)}"
490
+ return ""
491
+
492
+ # -- log parsing: activity
493
+
494
+ def extract_activity_from_text(self, text: str, *, tail_lines: int = 500) -> dict[str, Any]:
495
+ from ..cli import plain_log_text
496
+
497
+ lines = text.splitlines()[-tail_lines:]
498
+ sessions: set[str] = set()
499
+ subagent_sessions: set[str] = set()
500
+ touched_files: list[str] = []
501
+ latest: dict[str, Any] = {}
502
+ event_count = 0
503
+
504
+ def remember(
505
+ session_id: str | None,
506
+ *,
507
+ mode: str | None = None,
508
+ agent: str | None = None,
509
+ model: str | None = None,
510
+ message: str | None = None,
511
+ timestamp: str | None = None,
512
+ ) -> None:
513
+ nonlocal event_count, latest
514
+ normalized_session = normalize_agent_value(session_id)
515
+ if not normalized_session:
516
+ return
517
+ event_count += 1
518
+ sessions.add(normalized_session)
519
+ normalized_mode = normalize_agent_value(mode)
520
+ if normalized_mode == "subagent":
521
+ subagent_sessions.add(normalized_session)
522
+ latest = {
523
+ "latest_session_id": normalized_session,
524
+ "latest_mode": normalized_mode,
525
+ "latest_agent": normalize_agent_value(agent),
526
+ "latest_model": normalize_agent_value(model),
527
+ "latest_message": normalize_agent_value(message),
528
+ "latest_timestamp": normalize_agent_value(timestamp),
529
+ }
530
+
531
+ for raw_line in lines:
532
+ line = plain_log_text(raw_line).strip()
533
+ if not line:
534
+ continue
535
+ if line.startswith("{"):
536
+ try:
537
+ payload = json.loads(line)
538
+ except json.JSONDecodeError:
539
+ payload = None
540
+ if isinstance(payload, dict):
541
+ part = payload.get("part") if isinstance(payload.get("part"), dict) else {}
542
+ session_id = payload.get("sessionID") or part.get("sessionID")
543
+ if not session_id:
544
+ session_id = payload.get("turnID") or (part or {}).get("turnID")
545
+ remember(
546
+ str(session_id or ""),
547
+ mode=str(part.get("mode", "") if isinstance(part, dict) else ""),
548
+ agent=str(part.get("agent", "") if isinstance(part, dict) else ""),
549
+ message=str(payload.get("type") or ""),
550
+ timestamp=str(payload.get("timestamp") or ""),
551
+ )
552
+ continue
553
+
554
+ values = parse_log_key_values(line)
555
+ session_id = values.get("session.id")
556
+ if not session_id and "message=created" in line:
557
+ session_id = values.get("id")
558
+ if session_id:
559
+ remember(
560
+ session_id,
561
+ mode=values.get("mode"),
562
+ agent=values.get("agent"),
563
+ model=values.get("modelID") or values.get("llm.model") or values.get("model"),
564
+ message=values.get("message"),
565
+ timestamp=values.get("timestamp"),
566
+ )
567
+ touched = values.get("file") if values.get("message") == "touching file" else None
568
+ if touched:
569
+ touched_files.append(touched)
570
+
571
+ latest.update(
572
+ {
573
+ "event_count": event_count,
574
+ "session_count": len(sessions),
575
+ "subagent_session_count": len(subagent_sessions),
576
+ "has_subagent_activity": bool(subagent_sessions) or latest.get("latest_mode") == "subagent",
577
+ "touched_file_count": len(touched_files),
578
+ "latest_touched_file": touched_files[-1] if touched_files else "",
579
+ }
580
+ )
581
+ return latest
582
+
583
+
584
+ def _mimocode_active_model(execution: dict[str, Any]) -> str:
585
+ for key in ("actual_model", "model"):
586
+ value = normalize_agent_value(str(execution.get(key) or ""))
587
+ if value and value != "inherit":
588
+ return value
589
+ return ""
590
+
591
+
592
+ def _mimocode_set_option_before_message(command: list[str], flag: str, value: str) -> list[str]:
593
+ for index, item in enumerate(command):
594
+ text = str(item)
595
+ if text == flag:
596
+ if index + 1 >= len(command):
597
+ raise RuntimeError(f"{flag} is present without a following value")
598
+ result = list(command)
599
+ result[index + 1] = value
600
+ return result
601
+ if text.startswith(f"{flag}="):
602
+ result = list(command)
603
+ result[index] = f"{flag}={value}"
604
+ return result
605
+ insert_at = len(command)
606
+ for index, item in enumerate(command):
607
+ if str(item) == DEFAULT_ATTACHED_INSTRUCTION_PROMPT:
608
+ insert_at = index
609
+ break
610
+ return [*command[:insert_at], flag, value, *command[insert_at:]]
611
+
612
+
613
+ # -- shared session helpers (same as opencode.py)
614
+
615
+ def _ensure_session_record(
616
+ records: dict[str, dict[str, Any]], session_id: str
617
+ ) -> dict[str, Any]:
618
+ record = records.get(session_id)
619
+ if record is None:
620
+ record = {
621
+ "session_id": session_id,
622
+ "parent_id": None,
623
+ "agent": None,
624
+ "title": None,
625
+ "provider": None,
626
+ "model": None,
627
+ "mode": None,
628
+ "first_seen": None,
629
+ "last_seen": None,
630
+ "step_count": 0,
631
+ "tool_call_count": 0,
632
+ "text_part_count": 0,
633
+ "error_count": 0,
634
+ "tokens": {"input": 0, "output": 0, "reasoning": 0, "cache_read": 0, "cache_write": 0},
635
+ }
636
+ records[session_id] = record
637
+ return record
638
+
639
+
640
+ def _update_session_seen(record: dict[str, Any], timestamp: str | None) -> None:
641
+ if not timestamp:
642
+ return
643
+ if record.get("first_seen") is None or str(timestamp) < str(record.get("first_seen")):
644
+ record["first_seen"] = timestamp
645
+ if record.get("last_seen") is None or str(timestamp) > str(record.get("last_seen")):
646
+ record["last_seen"] = timestamp
647
+
648
+
649
+ def _session_timestamp_from_json(payload: dict[str, Any]) -> str | None:
650
+ import datetime as dt
651
+
652
+ value = payload.get("timestamp")
653
+ if isinstance(value, (int, float)):
654
+ try:
655
+ return dt.datetime.fromtimestamp(value / 1000, tz=dt.timezone.utc).isoformat()
656
+ except (OverflowError, OSError, ValueError):
657
+ return str(value)
658
+ if value is None:
659
+ return None
660
+ return str(value)
661
+
662
+
663
+ def _apply_step_tokens(record: dict[str, Any], tokens: dict[str, Any]) -> None:
664
+ bucket = record.setdefault("tokens", {})
665
+ for key in ("input", "output", "reasoning"):
666
+ value = tokens.get(key)
667
+ if isinstance(value, int):
668
+ bucket[key] = int(bucket.get(key, 0)) + value
669
+ cache = tokens.get("cache")
670
+ if isinstance(cache, dict):
671
+ read = cache.get("read")
672
+ write = cache.get("write")
673
+ if isinstance(read, int):
674
+ bucket["cache_read"] = int(bucket.get("cache_read", 0)) + read
675
+ if isinstance(write, int):
676
+ bucket["cache_write"] = int(bucket.get("cache_write", 0)) + write