oira666_pi-subagent 0.3.16 → 0.3.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.
package/README.md CHANGED
@@ -235,7 +235,7 @@ Note: crash-resume covers `subagents` calls only. An interrupted `resume_subagen
235
235
  ## Resumable Subagents by Name (`resume_subagents`)
236
236
 
237
237
  Every subagent run is assigned a random, durable human first name from a bundled
238
- list of 500 popular American names — for example `John`, `Maria`, or `Elena`.
238
+ list of 1000 culturally diverse names — for example `John`, `Octavian`, or `Vishnu`.
239
239
  Names are never reused anywhere in the same delegation tree. The name is
240
240
  returned together with the agent type and shown in every TUI view.
241
241
 
package/agent-names.ts ADDED
@@ -0,0 +1,126 @@
1
+ /** 1000 culturally diverse given names used for human-friendly subagent identities. */
2
+ export const AGENT_NAMES = [
3
+ // Common masculine names
4
+ "James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher",
5
+ "Charles", "Daniel", "Matthew", "Anthony", "Mark", "Donald", "Steven", "Andrew", "Paul", "Joshua",
6
+ "Kenneth", "Kevin", "Brian", "George", "Timothy", "Ronald", "Edward", "Jason", "Jeffrey", "Ryan",
7
+ "Jacob", "Gary", "Nicholas", "Eric", "Jonathan", "Stephen", "Larry", "Justin", "Scott", "Brandon",
8
+ "Benjamin", "Samuel", "Gregory", "Alexander", "Patrick", "Frank", "Raymond", "Jack", "Dennis", "Jerry",
9
+ "Tyler", "Aaron", "Jose", "Adam", "Nathan", "Henry", "Douglas", "Zachary", "Peter", "Kyle",
10
+ "Walter", "Ethan", "Jeremy", "Harold", "Keith", "Christian", "Roger", "Noah", "Gerald", "Carl",
11
+ "Terry", "Sean", "Austin", "Arthur", "Lawrence", "Jesse", "Dylan", "Bryan", "Joe", "Jordan",
12
+ "Billy", "Bruce", "Albert", "Willie", "Gabriel", "Logan", "Alan", "Juan", "Wayne", "Roy",
13
+ "Ralph", "Randy", "Eugene", "Vincent", "Russell", "Elijah", "Louis", "Bobby", "Philip", "Johnny",
14
+ "Howard", "Isaac", "Harry", "Victor", "Martin", "Ernest", "Phillip", "Todd", "Craig", "Shawn",
15
+ "Clarence", "Carlos", "Caleb", "Blake", "Mason", "Luke", "Liam", "Owen", "Nathaniel", "Cameron",
16
+ "Hunter", "Connor", "Adrian", "Julian", "Jeremiah", "Angel", "Isaiah", "Evan", "Colton", "Gavin",
17
+ "Dominic", "Cooper", "Ian", "Carson", "Jaxon", "Theodore", "Hudson", "Lincoln", "Asher", "Wyatt",
18
+ "Leo", "Ezra", "Miles", "Micah", "Silas", "Roman", "Wesley", "Brooks", "Bennett", "Parker",
19
+ "Beau", "Weston", "Damian", "Sawyer", "Emmett", "Harrison", "Cole", "Maxwell", "Holden", "Antonio",
20
+ "Miguel", "Oscar", "Diego", "Alejandro", "Marco", "Luis", "Javier", "Sergio", "Ricardo", "Manuel",
21
+ "Roberto", "Francisco", "Eduardo", "Fernando", "Ruben", "Raul", "Andres", "Hector", "Edgar", "Mario",
22
+ "Derek", "Trevor", "Travis", "Cody", "Dustin", "Corey", "Brett", "Chad", "Bradley", "Spencer",
23
+ "Grant", "Joel", "Dean", "Dale", "Glenn", "Stanley", "Leonard", "Francis", "Herbert", "Frederick",
24
+ "Norman", "Melvin", "Marvin", "Gordon", "Allen", "Bernard", "Clifford", "Warren", "Curtis", "Darren",
25
+ "Troy", "Marcus", "Derrick", "Andre", "Terrence", "Maurice", "Darius", "Malcolm", "Xavier", "Preston",
26
+ "Grayson", "Easton", "Nolan", "Everett", "Axel", "Emmanuel", "Kingston", "Elliot", "Tim", "Simon",
27
+ "Riley", "Finn", "Jasper", "Milo", "Rowan", "Declan", "Graham", "Max", "Nash", "Reid",
28
+ "Lane", "Tucker", "Carter", "Chase", "Coleman", "Bryce", "Hayden", "Aidan", "Jonah", "Jonas",
29
+
30
+ // Common feminine names
31
+ "Mary", "Patricia", "Jennifer", "Linda", "Elizabeth", "Barbara", "Susan", "Jessica", "Sarah", "Karen",
32
+ "Lisa", "Nancy", "Betty", "Margaret", "Sandra", "Ashley", "Kimberly", "Emily", "Donna", "Michelle",
33
+ "Carol", "Amanda", "Melissa", "Deborah", "Stephanie", "Dorothy", "Rebecca", "Sharon", "Laura", "Cynthia",
34
+ "Amy", "Kathleen", "Angela", "Shirley", "Brenda", "Emma", "Anna", "Pamela", "Nicole", "Samantha",
35
+ "Katherine", "Christine", "Debra", "Rachel", "Carolyn", "Janet", "Maria", "Heather", "Diane", "Julie",
36
+ "Joyce", "Victoria", "Kelly", "Christina", "Lauren", "Joan", "Evelyn", "Olivia", "Judith", "Megan",
37
+ "Cheryl", "Martha", "Andrea", "Frances", "Hannah", "Jacqueline", "Ann", "Gloria", "Jean", "Kathryn",
38
+ "Alice", "Teresa", "Sara", "Janice", "Doris", "Madison", "Julia", "Grace", "Judy", "Abigail",
39
+ "Marie", "Denise", "Beverly", "Amber", "Theresa", "Marilyn", "Danielle", "Diana", "Brittany", "Natalie",
40
+ "Sophia", "Rose", "Isabella", "Alexis", "Kayla", "Charlotte", "Lori", "Alexandra", "Savannah", "Brooklyn",
41
+ "Bella", "Claire", "Skylar", "Lucy", "Paisley", "Everly", "Caroline", "Nova", "Genesis", "Emilia",
42
+ "Kennedy", "Maya", "Willow", "Kinsley", "Naomi", "Aaliyah", "Elena", "Mckenna", "Ariana", "Allison",
43
+ "Gabriella", "Margot", "Madelyn", "Cora", "Ruby", "Eva", "Serenity", "Autumn", "Adeline", "Hailey",
44
+ "Gianna", "Valentina", "Isla", "Eliana", "Quinn", "Nevaeh", "Ivy", "Sadie", "Piper", "Lydia",
45
+ "Alexa", "Josephine", "Emery", "Phoebe", "Delilah", "Arianna", "Vivian", "Kaylee", "Sophie", "Brielle",
46
+ "Madeline", "Peyton", "Rylee", "Clara", "Hadley", "Melanie", "Mackenzie", "Reagan", "Adalynn", "Liliana",
47
+ "Aubree", "Jade", "Miranda", "Isabelle", "Natalia", "Raelynn", "Dakota", "Athena", "Ximena", "Arya",
48
+ "Leilani", "Taylor", "Faith", "Lena", "Kylie", "Miriam", "Kate", "Summer", "Lyla", "Brooke",
49
+ "Amaya", "Eliza", "Brianna", "Bailey", "Nina", "Khloe", "Jasmine", "Melody", "Isabel", "Norah",
50
+ "Annabelle", "Valeria", "Emerson", "Cecilia", "Valerie", "Molly", "Reese", "Aliyah", "Lilly", "Blair",
51
+ "Finley", "Morgan", "Sydney", "Jordyn", "Eloise", "Trinity", "Daisy", "Catherine", "Lola", "Genevieve",
52
+ "Marley", "Arabella", "Harmony", "Elise", "Remi", "Teagan", "Evie", "London", "Sloane", "Laila",
53
+ "Lucia", "Willa", "Juliana", "Gracie", "June", "Tessa", "Ada", "Camille", "Hope", "Samara",
54
+ "Rosalie", "Ruth", "Fiona", "Georgia", "Noelle", "Vanessa", "Daniela", "Paige", "Violet", "Presley",
55
+ "Adriana", "Joanna", "Giselle", "Harper", "Avery", "Scarlett", "Aria", "Ellie", "Chloe", "Layla",
56
+
57
+ // Ancient Greek, Roman, and Mediterranean names
58
+ "Achilles", "Aeschylus", "Agamemnon", "Alcibiades", "Andromache", "Antigone", "Apollonia", "Archimedes", "Aristides", "Aspasia",
59
+ "Berenice", "Briseis", "Calliope", "Cassander", "Cassia", "Cato", "Cicero", "Cleisthenes", "Clio", "Cornelia",
60
+ "Cyprian", "Damaris", "Demetrius", "Diogenes", "Electra", "Epictetus", "Eudora", "Euripides", "Galen", "Hecuba",
61
+ "Herodotus", "Hippolyta", "Horatia", "Hypatia", "Ianthe", "Isocrates", "Laodamia", "Leander", "Livia", "Lysander",
62
+ "Octavia", "Octavian", "Orestes", "Pericles", "Petronilla", "Plutarch", "Priam", "Sappho", "Seneca", "Themistocles",
63
+
64
+ // Norse, Celtic, and early Germanic names
65
+ "Aethelred", "Alaric", "Alfhild", "Ansgar", "Arnfinn", "Audhild", "Beowulf", "Boudica", "Branwen", "Brennus",
66
+ "Brynhild", "Cadwaladr", "Caradoc", "Cerdic", "Cormac", "Cunegunda", "Dagmar", "Eadric", "Eir", "Eirik",
67
+ "Embla", "Faramund", "Fergus", "Freydis", "Gudrun", "Gunnar", "Guthrum", "Gwendolen", "Halfdan", "Hildegard",
68
+ "Hrolf", "Iseult", "Ivar", "Leif", "Maeve", "Niamh", "Olwen", "Orlaith", "Ragnhild", "Ragnar",
69
+ "Rhiannon", "Sigfrid", "Sigrid", "Sigrun", "Somerled", "Svanhild", "Taliesin", "Theodelinda", "Torsten", "Yseult",
70
+
71
+ // Medieval, Byzantine, Slavic, and Baltic names
72
+ "Aldona", "Basilissa", "Boleslav", "Borivoj", "Bozena", "Bronislava", "Casimir", "Cyrilla", "Dobrawa", "Dragomir",
73
+ "Drazan", "Eudokia", "Euphemia", "Fevronia", "Gavrila", "Gleb", "Jaromir", "Jelena", "Kaloyan", "Kresimir",
74
+ "Ladislav", "Ljubica", "Ludmila", "Mieszko", "Milica", "Milos", "Miroslav", "Mstislav", "Nadezhda", "Niketas",
75
+ "Perun", "Pribislav", "Radoslav", "Rostislav", "Simeon", "Slavomir", "Sviatoslav", "Theodora", "Tomislav", "Vaclava",
76
+ "Vasilisa", "Vesna", "Viesturs", "Vladimir", "Vseslav", "Vytautas", "Yaroslav", "Zbigniew", "Zdislava", "Zvonimir",
77
+
78
+ // Ancient Egyptian, Mesopotamian, Persian, Armenian, and Georgian names
79
+ "Ahmose", "Amasis", "Amenemhat", "Ankhesenamun", "Ardashir", "Arsinoe", "Artabanus", "Artaxerxes", "Ashurbanipal", "Atossa",
80
+ "Bardiya", "Cambyses", "Cyrus", "Enheduanna", "Esarhaddon", "Gilgamesh", "Hatshepsut", "Horemheb", "Imhotep", "Ishtar",
81
+ "Kassandane", "Khafre", "Khufu", "Mandane", "Marduk", "Meritamen", "Mithridates", "Nabonidus", "Naram-Sin", "Nebuchadnezzar",
82
+ "Nefertari", "Nefertiti", "Neithhotep", "Nitocris", "Parmys", "Parysatis", "Pharnaces", "Psamtik", "Roxana", "Sargon",
83
+ "Semiramis", "Shapur", "Sinsharishkun", "Tahmasp", "Tamar", "Tigran", "Tiridates", "Tomyris", "Xerxes", "Zenobia",
84
+
85
+ // South Asian historical, literary, and traditional names
86
+ "Abhimanyu", "Agastya", "Amrapali", "Anasuya", "Arjuna", "Ashoka", "Bharata", "Bhaskara", "Bimbisara", "Chanakya",
87
+ "Chandragupta", "Charulata", "Damayanti", "Dhanvantari", "Draupadi", "Gargi", "Harsha", "Hemachandra", "Ila", "Indrajit",
88
+ "Jambavati", "Janaka", "Kalidasa", "Kanishka", "Karna", "Kausalya", "Krishna", "Lalitaditya", "Lopamudra", "Maitreyi",
89
+ "Mandodari", "Mirabai", "Nachiketa", "Narasimha", "Padmini", "Panini", "Parvati", "Prithviraj", "Razia", "Samudragupta",
90
+ "Savitri", "Shakuntala", "Shivaji", "Sita", "Subhadra", "Tansen", "Udayana", "Vashti", "Vikramaditya", "Vishnu",
91
+
92
+ // East Asian historical and legendary names
93
+ "Akiko", "Amaterasu", "Benkei", "Chiyome", "Okinagatarashi", "Himiko", "Tokimune", "Izumi", "Kaguya", "Kanetsugu",
94
+ "Kiyomori", "Masako", "Masamune", "Murasaki", "Nobunaga", "Raikou", "Sei", "Shingen", "Tadakatsu", "Tomoe",
95
+ "Hideyoshi", "Yamato", "Yoritomo", "Yoshitsune", "Yukimura", "Baochai", "Zhao", "Cao", "Chang'e", "Diaochan",
96
+ "Fuxi", "Guanyu", "Zhu", "Mulan", "Bai", "Bei", "Nuwa", "Zheng", "Ping", "Quan",
97
+ "Shimin", "Qiang", "Meiniang", "Ji", "Xishi", "Xuanzang", "Sun-sin", "Gwan-sun", "He", "Liang",
98
+
99
+ // Southeast Asian, Central Asian, and steppe names
100
+ "Airlangga", "Anawrahta", "Bayinnaung", "Borommatrailokkanat", "Champa", "Chulalongkorn", "Diponegoro", "Mada", "Tuah", "Rajasanagara",
101
+ "Jayavarman", "Kartini", "Arok", "Kertanegara", "Lakshmana", "Mahendravarman", "Parameswara", "Mulavarman", "Srikandi", "Suryavarman",
102
+ "Tribhuwana", "TrưngTrắc", "TrưngNhị", "Udayadityavarman", "Visay", "Arslan", "Babur", "Batu", "Bumin", "Chagatai",
103
+ "Genghis", "Hulagu", "Jebe", "Kublai", "Manas", "Möngke", "Nader", "Ogedei", "Roxelana", "Seljuk",
104
+ "Subutai", "Tokhtamysh", "Temujin", "Timur", "Tomris", "Tughril", "Taraghay", "Yesugei", "Zahiruddin", "Zebunissa",
105
+
106
+ // African historical, royal, and traditional names
107
+ "Amina", "Amanirenas", "Amanishakheto", "Askia", "Behanzin", "Bilqis", "Candace", "Cetshwayo", "Chaka", "Dihya",
108
+ "Efunroye", "Ezana", "Gudit", "Hannibal", "Hanno", "Amanitore", "Idia", "Orompoto", "Jaja", "Taharqa",
109
+ "Shanakhdakheto", "Kassa", "Khama", "Lalibela", "LatDior", "Liholiho", "Lukeni", "Makeda", "Sakura", "Mantatisi",
110
+ "Menen", "Menelik", "Mkabayi", "Moremi", "Moshoeshoe", "Mpande", "Mzilikazi", "Nandi", "YaaAsantewaa", "Njoya",
111
+ "Njinga", "Ewuare", "Osei", "Piankhi", "Prempeh", "Ranavalona", "Sarraounia", "Sekhukhune", "Shaka", "Sundiata",
112
+
113
+ // Indigenous American and Pacific historical and traditional names
114
+ "Ahuizotl", "Anacaona", "Atahualpa", "Caupolicán", "Cuitlahuac", "Cuauhtemoc", "Guarocuya", "Huascar", "Itzcoatl", "Lautaro",
115
+ "Malinalli", "Manco", "Moctezuma", "Nezahualcoyotl", "Ollantay", "Pachacuti", "Quispe", "Rumiñahui", "Sayri", "Sinchi",
116
+ "Tecuichpo", "Tlahuicole", "Tupac", "Xicotencatl", "Yma", "Hine-nui-te-pō", "Hongi", "Kamehameha", "Kaʻahumanu", "Keōpūolani",
117
+ "Kupe", "Liliʻuokalani", "Makea", "Maui", "Olomu", "Ngarimu", "Pakalitha", "Pele", "Pōmare", "Ruatara",
118
+ "Salamasina", "Tāwhiao", "Te Puea", "Tupaia", "Tūtānekai", "Uenuku", "Vaiola", "Whina", "Wherowhero", "Yosihiko",
119
+
120
+ // Middle Eastern, North African, Iberian, and Jewish historical names
121
+ "AbdAl-Rahman", "Aisha", "Hasan", "Ja'far", "Pelayo", "Walid", "Husayn", "Badr", "Bintou", "Abdallah",
122
+ "Bohemond", "Rodrigo", "Fadila", "Fatima", "Qasim", "Ghazala", "Hafsa", "Harun", "Hasdrubal", "Muhammad",
123
+ "Idris", "Ishaq", "Jahanara", "Khadija", "Khayzuran", "Leovigild", "Lubna", "Moshe", "Marwan", "Maslama",
124
+ "Musa", "Nasir", "Rabi'a", "Rashid", "Saadia", "Salahuddin", "Shajar", "Shirin", "Suhaila", "Tariq",
125
+ "Theodoric", "Urraca", "Wallada", "Yehuda", "Yusuf", "Zaynab", "Ziryab", "Zipporah", "Zubaida", "Zuleika",
126
+ ] as const;
package/index.ts CHANGED
@@ -41,6 +41,7 @@ import {
41
41
  SUBAGENT_NAMES_CUSTOM_TYPE,
42
42
  } from "./names.js";
43
43
  import {
44
+ clearRenderCaches,
44
45
  recordToolCallStart,
45
46
  renderCall,
46
47
  renderResult,
@@ -73,6 +74,7 @@ import {
73
74
  type SingleResult,
74
75
  type SubagentDetails,
75
76
  type SubagentUsageSummary,
77
+ type UsageStats,
76
78
  DEFAULT_DELEGATION_MODE,
77
79
  buildLiveSubagentDetails,
78
80
  buildSubagentDetails,
@@ -507,44 +509,63 @@ function collectLiveUsageSummary(details: SubagentDetails): SubagentUsageSummary
507
509
  return summary;
508
510
  }
509
511
 
512
+ type PersistedUsageTotals = {
513
+ leafId: unknown;
514
+ hasEntries: boolean;
515
+ parentUsage: UsageStats;
516
+ subagents: SubagentUsageSummary;
517
+ };
518
+
519
+ // SessionManager owns the history; a WeakMap lets its one current aggregate be
520
+ // reclaimed with the manager. Repeated progress/heartbeat updates no longer
521
+ // rescan a week-long branch when its leaf has not changed.
522
+ const persistedUsageCache = new WeakMap<object, PersistedUsageTotals>();
523
+
510
524
  function collectCombinedUsageStatusLine(
511
525
  ctx: any,
512
526
  liveSummaries: SubagentUsageSummary[] = [],
513
527
  ): string | undefined {
514
- const entries = typeof ctx?.sessionManager?.getEntries === "function" || typeof ctx?.sessionManager?.getBranch === "function"
515
- ? branchEntries(ctx)
516
- : [];
517
- if (entries.length === 0 && liveSummaries.length === 0) return undefined;
518
-
519
- const parentUsage = emptyUsage();
520
- const subagents = emptyUsageSummary();
521
- for (const entry of entries as any[]) {
522
- if (entry?.type !== "message") continue;
523
- const msg = entry.message;
524
- if (!msg) continue;
525
- if (msg.role === "assistant" && msg.provider !== RESUME_PROVIDER) {
526
- const usage = msg.usage;
527
- if (usage) {
528
- parentUsage.input += usage.input || 0;
529
- parentUsage.output += usage.output || 0;
530
- parentUsage.cacheRead += usage.cacheRead || 0;
531
- parentUsage.cacheWrite += usage.cacheWrite || 0;
532
- parentUsage.cost += typeof usage.cost === "number" ? usage.cost : usage.cost?.total || 0;
533
- parentUsage.turns += 1;
528
+ const manager = ctx?.sessionManager;
529
+ const canReadEntries = typeof manager?.getEntries === "function" || typeof manager?.getBranch === "function";
530
+ const leafId = typeof manager?.getLeafId === "function" ? manager.getLeafId() : undefined;
531
+ const cacheKey = manager !== null && typeof manager === "object" ? manager as object : undefined;
532
+ let persisted = cacheKey && leafId !== undefined ? persistedUsageCache.get(cacheKey) : undefined;
533
+
534
+ if (!persisted || persisted.leafId !== leafId) {
535
+ const entries = canReadEntries ? branchEntries(ctx) : [];
536
+ const parentUsage = emptyUsage();
537
+ const subagents = emptyUsageSummary();
538
+ for (const entry of entries as any[]) {
539
+ if (entry?.type !== "message") continue;
540
+ const msg = entry.message;
541
+ if (!msg) continue;
542
+ if (msg.role === "assistant" && msg.provider !== RESUME_PROVIDER) {
543
+ const usage = msg.usage;
544
+ if (usage) {
545
+ parentUsage.input += usage.input || 0;
546
+ parentUsage.output += usage.output || 0;
547
+ parentUsage.cacheRead += usage.cacheRead || 0;
548
+ parentUsage.cacheWrite += usage.cacheWrite || 0;
549
+ parentUsage.cost += typeof usage.cost === "number" ? usage.cost : usage.cost?.total || 0;
550
+ parentUsage.turns += 1;
551
+ }
552
+ }
553
+ if (msg.role === "toolResult" && isSubagentToolName(msg.toolName) && isSubagentDetails(msg.details)) {
554
+ addUsageSummary(
555
+ subagents,
556
+ msg.details.usageSummary ?? usageSummaryFromUsage(msg.details.aggregatedUsage),
557
+ );
534
558
  }
535
559
  }
536
- if (msg.role === "toolResult" && isSubagentToolName(msg.toolName) && isSubagentDetails(msg.details)) {
537
- addUsageSummary(
538
- subagents,
539
- msg.details.usageSummary ?? usageSummaryFromUsage(msg.details.aggregatedUsage),
540
- );
541
- }
542
- }
543
- for (const liveSummary of liveSummaries) {
544
- addUsageSummary(subagents, liveSummary);
560
+ persisted = { leafId, hasEntries: entries.length > 0, parentUsage, subagents };
561
+ if (cacheKey && leafId !== undefined) persistedUsageCache.set(cacheKey, persisted);
545
562
  }
546
- const subagentUsage = usageSummaryToUsageStats(subagents) ?? emptyUsage();
547
- addUsage(parentUsage, subagentUsage);
563
+
564
+ if (!persisted.hasEntries && liveSummaries.length === 0) return undefined;
565
+ const parentUsage = { ...persisted.parentUsage };
566
+ const subagents = { ...persisted.subagents };
567
+ for (const liveSummary of liveSummaries) addUsageSummary(subagents, liveSummary);
568
+ addUsage(parentUsage, usageSummaryToUsageStats(subagents) ?? emptyUsage());
548
569
  return formatCombinedUsageStatusLine(parentUsage, subagents.subagentCount);
549
570
  }
550
571
 
@@ -1464,6 +1485,11 @@ export default function (pi: ExtensionAPI) {
1464
1485
  activeSubagentUsageSummaries.clear();
1465
1486
  forcedErrorToolCallIds.clear();
1466
1487
  activeSubagents.clear();
1488
+ activeResumeNames.clear();
1489
+ approvedProjectAgentDirsForSession.clear();
1490
+ latestBroadcastTargets.all = [];
1491
+ latestBroadcastTargets.youngest = [];
1492
+ clearRenderCaches();
1467
1493
  });
1468
1494
 
1469
1495
  /**
@@ -1942,8 +1968,8 @@ ${agentList}\n\n${subagentsGuidance}\n\n${delegationGuardGuidance}${resumeGuidan
1942
1968
  },
1943
1969
 
1944
1970
  renderCall: (args, theme, context) => renderCall(args, theme, context),
1945
- renderResult: (result, { expanded }, theme) =>
1946
- renderResult(result, expanded, theme),
1971
+ renderResult: (result, { expanded }, theme, context) =>
1972
+ renderResult(result, expanded, theme, context),
1947
1973
  });
1948
1974
  };
1949
1975
 
@@ -2158,8 +2184,8 @@ ${agentList}\n\n${subagentsGuidance}\n\n${delegationGuardGuidance}${resumeGuidan
2158
2184
  },
2159
2185
 
2160
2186
  renderCall: (args, theme, context) => renderResumeCall(args, theme, context),
2161
- renderResult: (result, { expanded }, theme) =>
2162
- renderResult(result, expanded, theme),
2187
+ renderResult: (result, { expanded }, theme, context) =>
2188
+ renderResult(result, expanded, theme, context),
2163
2189
  });
2164
2190
  };
2165
2191
 
@@ -2225,34 +2251,38 @@ ${agentList}\n\n${subagentsGuidance}\n\n${delegationGuardGuidance}${resumeGuidan
2225
2251
  }
2226
2252
 
2227
2253
  let activeId: number | undefined;
2228
- const result = await runAgentSubprocess({
2229
- cwd: defaultCwd,
2230
- agents,
2231
- agentName,
2232
- task,
2233
- subagentName,
2234
- parentDepth: currentDepth,
2235
- parentAgentStack: ancestorAgentStack,
2236
- maxDepth,
2237
- preventCycles,
2238
- signal,
2239
- onUpdate,
2240
- makeDetails: makeDetails("single"),
2241
- sessionDir: previousResult?.sessionDir ?? sessionDir,
2242
- sessionRoot: currentSubagentSessionRoot,
2243
- namesFile: currentNamesFile || undefined,
2244
- resumeSession: resumeExistingSession,
2245
- initialResult: previousResult,
2246
- fallbackModel,
2247
- onHandle: (handle) => {
2248
- activeId = topLevelBaseId;
2249
- activeSubagents.set(activeId, { agent: agentName, task, handle, name: subagentName });
2254
+ let result: SingleResult;
2255
+ try {
2256
+ result = await runAgentSubprocess({
2257
+ cwd: defaultCwd,
2258
+ agents,
2259
+ agentName,
2260
+ task,
2261
+ subagentName,
2262
+ parentDepth: currentDepth,
2263
+ parentAgentStack: ancestorAgentStack,
2264
+ maxDepth,
2265
+ preventCycles,
2266
+ signal,
2267
+ onUpdate,
2268
+ makeDetails: makeDetails("single"),
2269
+ sessionDir: previousResult?.sessionDir ?? sessionDir,
2270
+ sessionRoot: currentSubagentSessionRoot,
2271
+ namesFile: currentNamesFile || undefined,
2272
+ resumeSession: resumeExistingSession,
2273
+ initialResult: previousResult,
2274
+ fallbackModel,
2275
+ onHandle: (handle) => {
2276
+ activeId = topLevelBaseId;
2277
+ activeSubagents.set(activeId, { agent: agentName, task, handle, name: subagentName });
2278
+ updateLatestBroadcastTargets(undefined);
2279
+ },
2280
+ });
2281
+ } finally {
2282
+ if (activeId !== undefined) {
2283
+ activeSubagents.delete(activeId);
2250
2284
  updateLatestBroadcastTargets(undefined);
2251
- },
2252
- });
2253
- if (activeId !== undefined) {
2254
- activeSubagents.delete(activeId);
2255
- updateLatestBroadcastTargets(undefined);
2285
+ }
2256
2286
  }
2257
2287
 
2258
2288
  if (isResultError(result)) {
@@ -2332,6 +2362,7 @@ ${agentList}\n\n${subagentsGuidance}\n\n${delegationGuardGuidance}${resumeGuidan
2332
2362
  );
2333
2363
  } finally {
2334
2364
  for (const id of taskIds.values()) activeSubagents.delete(id);
2365
+ updateLatestBroadcastTargets(undefined);
2335
2366
  }
2336
2367
  }
2337
2368
  }
package/names.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Durable subagent name registry.
3
3
  *
4
4
  * Every spawned subagent gets a random human first name from the bundled
5
- * 500-name pool (e.g. `John`, `Maria`, `Elena`). Names are unique within one
5
+ * 1000-name culturally diverse pool (e.g. `John`, `Octavian`, `Vishnu`). Names are unique within one
6
6
  * delegation tree (the tree
7
7
  * rooted at the top-level pi session) and are persisted in a JSON registry
8
8
  * file under the subagent session root, so they survive process restarts.
@@ -21,7 +21,7 @@
21
21
  import * as fs from "node:fs";
22
22
  import * as path from "node:path";
23
23
  import { randomInt } from "node:crypto";
24
- import { AMERICAN_NAMES } from "./american-names.js";
24
+ import { AGENT_NAMES } from "./agent-names.js";
25
25
 
26
26
  export const SUBAGENT_NAMES_FILE_ENV = "PI_SUBAGENT_NAMES_FILE";
27
27
 
@@ -351,7 +351,7 @@ export async function updateNamesRegistry<T>(
351
351
 
352
352
  export function getAvailableSubagentNames(registry: NamesRegistry): string[] {
353
353
  const used = new Set(Object.keys(registry.agents).map((name) => name.toLowerCase()));
354
- return AMERICAN_NAMES.filter((name) => !used.has(name.toLowerCase()));
354
+ return AGENT_NAMES.filter((name) => !used.has(name.toLowerCase()));
355
355
  }
356
356
 
357
357
  export interface AllocateNameRequest {
@@ -377,7 +377,7 @@ export async function allocateSubagentNames(
377
377
  const available = getAvailableSubagentNames(registry);
378
378
  if (available.length < requests.length) {
379
379
  throw new Error(
380
- `The 500-name subagent pool is exhausted (${available.length} available, ${requests.length} requested).`,
380
+ `The ${AGENT_NAMES.length}-name subagent pool is exhausted (${available.length} available, ${requests.length} requested).`,
381
381
  );
382
382
  }
383
383
  for (const request of requests) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oira666_pi-subagent",
3
- "version": "0.3.16",
3
+ "version": "0.3.18",
4
4
  "description": "Subagent extension for Pi coding agent. Delegate tasks to specialized agents.",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -11,7 +11,7 @@
11
11
  "runner.ts",
12
12
  "resume.ts",
13
13
  "names.ts",
14
- "american-names.ts",
14
+ "agent-names.ts",
15
15
  "shared.ts",
16
16
  "render.ts",
17
17
  "tree.ts",