agent-theatre 1.2.2 → 1.3.0

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.
package/dist/cli.js CHANGED
@@ -300,9 +300,81 @@ function claimsSuccess(text) {
300
300
  if (HEDGE_LEXICON.some((r) => r.test(tail))) return false;
301
301
  return SUCCESS_LEXICON.some((r) => r.test(tail));
302
302
  }
303
- var ROW_TYPES = /* @__PURE__ */ new Set(["user", "assistant", "system"]);
304
303
  var obj2 = (x) => x && typeof x === "object" ? x : {};
305
304
  var str2 = (x) => typeof x === "string" ? x : void 0;
305
+ var TOOL_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "PostToolUseFailure"]);
306
+ function endReason(reason) {
307
+ switch (reason) {
308
+ case "clear":
309
+ case "logout":
310
+ case "prompt_input_exit":
311
+ return "user";
312
+ default:
313
+ return "stop";
314
+ }
315
+ }
316
+ function hookPayloadToEvents(payload, opts = {}) {
317
+ const p = obj2(payload);
318
+ const name = str2(p.hook_event_name);
319
+ const sessionId = str2(p.session_id) ?? "";
320
+ const ts = opts.now ?? Date.now();
321
+ if (!name) return { events: [], warnings: [{ code: "missing_field", detail: "hook_event_name" }] };
322
+ const cwd = str2(p.cwd) ?? "";
323
+ const ctx = { cwd, ...opts.home ? { home: opts.home } : {} };
324
+ const agentId = TOOL_EVENTS.has(name) ? str2(p.agent_id) : void 0;
325
+ const extra = agentId ? { agentId } : {};
326
+ let seq = 0;
327
+ const mk = (body, id = mintId(ts)) => ({ id, seq: seq++, ts, sessionId, source: "hook", ...extra, ...body });
328
+ const one = (body) => ({ events: [mk(body)], warnings: [] });
329
+ switch (name) {
330
+ case "SessionStart":
331
+ return one({ kind: "session_start", repoId: basename(cwd) || "repo" });
332
+ case "SessionEnd":
333
+ return one({ kind: "session_end", reason: endReason(str2(p.reason)), claimedSuccess: false });
334
+ case "Stop":
335
+ return one({ kind: "turn_end", claimedSuccess: claimsSuccess(str2(p.last_assistant_message)), ...noteOf(str2(p.last_assistant_message)) });
336
+ case "SubagentStart": {
337
+ const id = str2(p.agent_id) ?? "";
338
+ const label = str2(p.agent_type);
339
+ return { events: [mk({ kind: "subagent_start", childId: id, ...label ? { label } : {} })], warnings: [] };
340
+ }
341
+ case "SubagentStop":
342
+ return one({ kind: "subagent_stop", childId: str2(p.agent_id) ?? "", ok: true });
343
+ case "Notification": {
344
+ const t = str2(p.notification_type);
345
+ if (t === "permission_prompt") return one({ kind: "waiting_for_user", reason: "permission" });
346
+ if (t === "idle_prompt") return one({ kind: "waiting_for_user", reason: "idle" });
347
+ if (t === "elicitation_dialog") return one({ kind: "waiting_for_user", reason: "question" });
348
+ return { events: [], warnings: [] };
349
+ }
350
+ case "PostToolUseFailure":
351
+ return one({ kind: "error", where: str2(p.tool_name) ?? "tool", retrying: false });
352
+ case "PostToolUse": {
353
+ const tool = str2(p.tool_name);
354
+ if (!tool) return { events: [], warnings: [{ code: "missing_field", detail: "tool_name" }] };
355
+ const dur = typeof p.duration_ms === "number" ? { durationMs: p.duration_ms } : {};
356
+ const out = toolCallToOutcome({ name: tool, input: p.tool_input, response: p.tool_response, ...dur }, ctx);
357
+ const baseId = str2(p.tool_use_id) ?? mintId(ts);
358
+ const events = out.bodies.map((body, i) => mk(body, i === 0 ? baseId : `${baseId}:${i}`));
359
+ return { events, warnings: out.warning ? [out.warning] : [] };
360
+ }
361
+ case "PreToolUse":
362
+ case "UserPromptSubmit":
363
+ case "PreCompact":
364
+ case "PostCompact":
365
+ return { events: [], warnings: [] };
366
+ }
367
+ return { events: [], warnings: [{ code: "unknown_row_type", detail: name }] };
368
+ }
369
+ function noteOf(text) {
370
+ if (!text) return {};
371
+ const para = text.trim().split(/\n{2,}/).filter((x) => x.trim()).pop()?.replace(/\s+/g, " ").trim() ?? "";
372
+ if (!para) return {};
373
+ return { note: para.length > 240 ? "\u2026" + para.slice(-239) : para };
374
+ }
375
+ var ROW_TYPES = /* @__PURE__ */ new Set(["user", "assistant", "system"]);
376
+ var obj3 = (x) => x && typeof x === "object" ? x : {};
377
+ var str3 = (x) => typeof x === "string" ? x : void 0;
306
378
  function parseTranscript(text, opts = {}) {
307
379
  const rows = [];
308
380
  const warnings = [];
@@ -338,21 +410,21 @@ function parseTranscriptRows(rows, opts = {}) {
338
410
  events.push({ id, seq: seq++, ts, sessionId, source: "transcript", ...extra, ...body });
339
411
  };
340
412
  const tsOf = (row) => {
341
- const t = str2(row.timestamp);
413
+ const t = str3(row.timestamp);
342
414
  const n = t ? Date.parse(t) : Number.NaN;
343
415
  return Number.isFinite(n) ? n : Number.isFinite(lastTs) ? lastTs : 0;
344
416
  };
345
- const agentOf = (row) => str2(row.agentId) ?? (row.isSidechain === true ? opts.sidechainAgentId ?? "sidechain" : void 0);
417
+ const agentOf = (row) => str3(row.agentId) ?? (row.isSidechain === true ? opts.sidechainAgentId ?? "sidechain" : void 0);
346
418
  for (const raw of rows) {
347
- const row = obj2(raw);
348
- const type = str2(row.type) ?? "";
419
+ const row = obj3(raw);
420
+ const type = str3(row.type) ?? "";
349
421
  if (!ROW_TYPES.has(type)) {
350
422
  if (type) unknownTypes.add(type);
351
423
  continue;
352
424
  }
353
- if (!sessionId && str2(row.sessionId)) sessionId = str2(row.sessionId);
354
- if (!cwd && str2(row.cwd)) cwd = str2(row.cwd);
355
- if (!branch && str2(row.gitBranch)) branch = str2(row.gitBranch);
425
+ if (!sessionId && str3(row.sessionId)) sessionId = str3(row.sessionId);
426
+ if (!cwd && str3(row.cwd)) cwd = str3(row.cwd);
427
+ if (!branch && str3(row.gitBranch)) branch = str3(row.gitBranch);
356
428
  const ts = tsOf(row);
357
429
  if (!Number.isFinite(firstTs)) {
358
430
  firstTs = ts;
@@ -360,39 +432,39 @@ function parseTranscriptRows(rows, opts = {}) {
360
432
  }
361
433
  lastTs = ts;
362
434
  const agentId = agentOf(row);
363
- const message = obj2(row.message);
435
+ const message = obj3(row.message);
364
436
  const content = message.content;
365
437
  if (type === "system") {
366
438
  if (row.subtype === "api_error") {
367
439
  const attempt = typeof row.retryAttempt === "number" ? row.retryAttempt : 0;
368
440
  const max = typeof row.maxRetries === "number" ? row.maxRetries : 0;
369
- push(ts, str2(row.uuid) ?? `sys:${seq}`, { kind: "error", where: "api", retrying: attempt < max }, agentId ? { agentId } : {});
441
+ push(ts, str3(row.uuid) ?? `sys:${seq}`, { kind: "error", where: "api", retrying: attempt < max }, agentId ? { agentId } : {});
370
442
  }
371
443
  continue;
372
444
  }
373
445
  if (type === "assistant") {
374
446
  const blocks2 = Array.isArray(content) ? content : [];
375
447
  for (const b of blocks2) {
376
- const block = obj2(b);
377
- if (block.type === "tool_use" && str2(block.id) && str2(block.name)) {
378
- pending.set(str2(block.id), { name: str2(block.name), input: block.input, ts, ...agentId ? { agentId } : {} });
448
+ const block = obj3(b);
449
+ if (block.type === "tool_use" && str3(block.id) && str3(block.name)) {
450
+ pending.set(str3(block.id), { name: str3(block.name), input: block.input, ts, ...agentId ? { agentId } : {} });
379
451
  } else if (block.type === "text" && !agentId) {
380
- const t = str2(block.text);
452
+ const t = str3(block.text);
381
453
  if (t) lastAssistantText = t;
382
454
  }
383
455
  }
384
456
  if (typeof content === "string" && !agentId) lastAssistantText = content;
385
457
  if (message.stop_reason === "end_turn" && !agentId) {
386
- push(ts, `${str2(row.uuid) ?? seq}:turn`, { kind: "turn_end", claimedSuccess: claimsSuccess(lastAssistantText) });
458
+ push(ts, `${str3(row.uuid) ?? seq}:turn`, { kind: "turn_end", claimedSuccess: claimsSuccess(lastAssistantText), ...noteOf(lastAssistantText) });
387
459
  }
388
460
  continue;
389
461
  }
390
- if (row.toolDenialKind !== void 0) push(ts, `${str2(row.uuid) ?? seq}:deny`, { kind: "waiting_for_user", reason: "permission" });
462
+ if (row.toolDenialKind !== void 0) push(ts, `${str3(row.uuid) ?? seq}:deny`, { kind: "waiting_for_user", reason: "permission" });
391
463
  const blocks = Array.isArray(content) ? content : [];
392
464
  for (const b of blocks) {
393
- const block = obj2(b);
465
+ const block = obj3(b);
394
466
  if (block.type !== "tool_result") continue;
395
- const useId = str2(block.tool_use_id);
467
+ const useId = str3(block.tool_use_id);
396
468
  if (!useId) continue;
397
469
  const p = pending.get(useId);
398
470
  if (!p) {
@@ -413,7 +485,7 @@ function parseTranscriptRows(rows, opts = {}) {
413
485
  if (out.pendingSubagent) openSubagents.set(out.pendingSubagent.childId, useId);
414
486
  }
415
487
  if (blocks.length === 0 && typeof content === "string" && /\[Request interrupted by user/i.test(content)) {
416
- push(ts, `${str2(row.uuid) ?? seq}:interrupt`, { kind: "waiting_for_user", reason: "idle" });
488
+ push(ts, `${str3(row.uuid) ?? seq}:interrupt`, { kind: "waiting_for_user", reason: "idle" });
417
489
  }
418
490
  }
419
491
  for (const [useId, p] of pending) {
@@ -432,72 +504,6 @@ function parseTranscriptRows(rows, opts = {}) {
432
504
  }
433
505
  return { events, warnings };
434
506
  }
435
- var obj3 = (x) => x && typeof x === "object" ? x : {};
436
- var str3 = (x) => typeof x === "string" ? x : void 0;
437
- var TOOL_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "PostToolUseFailure"]);
438
- function endReason(reason) {
439
- switch (reason) {
440
- case "clear":
441
- case "logout":
442
- case "prompt_input_exit":
443
- return "user";
444
- default:
445
- return "stop";
446
- }
447
- }
448
- function hookPayloadToEvents(payload, opts = {}) {
449
- const p = obj3(payload);
450
- const name = str3(p.hook_event_name);
451
- const sessionId = str3(p.session_id) ?? "";
452
- const ts = opts.now ?? Date.now();
453
- if (!name) return { events: [], warnings: [{ code: "missing_field", detail: "hook_event_name" }] };
454
- const cwd = str3(p.cwd) ?? "";
455
- const ctx = { cwd, ...opts.home ? { home: opts.home } : {} };
456
- const agentId = TOOL_EVENTS.has(name) ? str3(p.agent_id) : void 0;
457
- const extra = agentId ? { agentId } : {};
458
- let seq = 0;
459
- const mk = (body, id = mintId(ts)) => ({ id, seq: seq++, ts, sessionId, source: "hook", ...extra, ...body });
460
- const one = (body) => ({ events: [mk(body)], warnings: [] });
461
- switch (name) {
462
- case "SessionStart":
463
- return one({ kind: "session_start", repoId: basename(cwd) || "repo" });
464
- case "SessionEnd":
465
- return one({ kind: "session_end", reason: endReason(str3(p.reason)), claimedSuccess: false });
466
- case "Stop":
467
- return one({ kind: "turn_end", claimedSuccess: claimsSuccess(str3(p.last_assistant_message)) });
468
- case "SubagentStart": {
469
- const id = str3(p.agent_id) ?? "";
470
- const label = str3(p.agent_type);
471
- return { events: [mk({ kind: "subagent_start", childId: id, ...label ? { label } : {} })], warnings: [] };
472
- }
473
- case "SubagentStop":
474
- return one({ kind: "subagent_stop", childId: str3(p.agent_id) ?? "", ok: true });
475
- case "Notification": {
476
- const t = str3(p.notification_type);
477
- if (t === "permission_prompt") return one({ kind: "waiting_for_user", reason: "permission" });
478
- if (t === "idle_prompt") return one({ kind: "waiting_for_user", reason: "idle" });
479
- if (t === "elicitation_dialog") return one({ kind: "waiting_for_user", reason: "question" });
480
- return { events: [], warnings: [] };
481
- }
482
- case "PostToolUseFailure":
483
- return one({ kind: "error", where: str3(p.tool_name) ?? "tool", retrying: false });
484
- case "PostToolUse": {
485
- const tool = str3(p.tool_name);
486
- if (!tool) return { events: [], warnings: [{ code: "missing_field", detail: "tool_name" }] };
487
- const dur = typeof p.duration_ms === "number" ? { durationMs: p.duration_ms } : {};
488
- const out = toolCallToOutcome({ name: tool, input: p.tool_input, response: p.tool_response, ...dur }, ctx);
489
- const baseId = str3(p.tool_use_id) ?? mintId(ts);
490
- const events = out.bodies.map((body, i) => mk(body, i === 0 ? baseId : `${baseId}:${i}`));
491
- return { events, warnings: out.warning ? [out.warning] : [] };
492
- }
493
- case "PreToolUse":
494
- case "UserPromptSubmit":
495
- case "PreCompact":
496
- case "PostCompact":
497
- return { events: [], warnings: [] };
498
- }
499
- return { events: [], warnings: [{ code: "unknown_row_type", detail: name }] };
500
- }
501
507
  function hashString(s) {
502
508
  let h = 2166136261;
503
509
  for (let i = 0; i < s.length; i++) {
@@ -1039,7 +1045,7 @@ var Director = class {
1039
1045
  this.emit(e, actor, { kind: "unverified_claim", gremlinId: gid }, 1400, this.mood.onClaimUnverified());
1040
1046
  }
1041
1047
  this.editedSinceTurn = false;
1042
- this.emit(e, actor, { kind: "your_turn" }, 1e3, this.mood.mood);
1048
+ this.emit(e, actor, { kind: "your_turn", ...e.note ? { note: e.note } : {} }, 1e3, this.mood.mood);
1043
1049
  break;
1044
1050
  }
1045
1051
  case "session_end":