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