pi-roundtable 0.22.5 → 0.23.1

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.
Files changed (129) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/README.md +35 -9
  3. package/README.zh-TW.md +51 -13
  4. package/docs/migrating-0.8.md +2 -2
  5. package/docs/plugins.md +351 -28
  6. package/examples/discord-adapter.ts +9 -1
  7. package/examples/seeds.test.ts +2 -2
  8. package/examples/seeds.ts +1 -2
  9. package/package.json +6 -2
  10. package/src/characters/catalog.ts +1055 -0
  11. package/src/characters/characters.css +68 -0
  12. package/src/characters/colors.ts +108 -0
  13. package/src/characters/compose.ts +281 -0
  14. package/src/characters/css.ts +63 -0
  15. package/src/characters/index.ts +33 -0
  16. package/src/characters/parse.ts +196 -0
  17. package/src/characters/parts-face.ts +354 -0
  18. package/src/characters/parts-hair.ts +56 -0
  19. package/src/characters/parts-hats.ts +57 -0
  20. package/src/characters/parts-outfits.ts +81 -0
  21. package/src/characters/parts-props.ts +137 -0
  22. package/src/characters/spec.ts +224 -0
  23. package/src/characters/suggest.ts +101 -0
  24. package/src/cli/checks/characters.ts +23 -0
  25. package/src/cli/checks/images.ts +5 -3
  26. package/src/cli/doctor.ts +2 -0
  27. package/src/core/agents/agent-claim.ts +30 -11
  28. package/src/core/agents/agent-dashboard.ts +1 -1
  29. package/src/core/agents/agent-messages.ts +43 -15
  30. package/src/core/agents/agent-prompt.ts +2 -4
  31. package/src/core/agents/agent-rules.ts +42 -3
  32. package/src/core/agents/agent-schema.ts +37 -15
  33. package/src/core/agents/agent-store.ts +57 -13
  34. package/src/core/agents/agent-team-fixture.ts +90 -14
  35. package/src/core/agents/agent-team.ts +83 -50
  36. package/src/core/agents/agent-tools.ts +94 -41
  37. package/src/core/agents/avatar-studio.ts +40 -4
  38. package/src/core/agents/character-png.ts +40 -0
  39. package/src/core/agents/group-messages.ts +7 -4
  40. package/src/core/agents/group-turns.ts +27 -14
  41. package/src/core/agents/team-editing.ts +99 -58
  42. package/src/core/agents/team-keys.ts +177 -11
  43. package/src/core/agents/team-lifecycle.ts +151 -84
  44. package/src/core/agents/team-options.ts +13 -6
  45. package/src/core/agents/team-status.ts +31 -13
  46. package/src/core/agents/team-text.ts +13 -3
  47. package/src/core/agents/team-turn-types.ts +25 -7
  48. package/src/core/agents/team-turns.ts +143 -28
  49. package/src/core/attachments/attachment-fetcher.ts +162 -64
  50. package/src/core/attachments/prompt-block.ts +7 -1
  51. package/src/core/attachments/tool-attachment.ts +20 -1
  52. package/src/core/attachments/turn-attachments.ts +18 -2
  53. package/src/core/builtin/agent-server.ts +103 -40
  54. package/src/core/builtin/discord.ts +4 -17
  55. package/src/core/builtin/modules.ts +6 -5
  56. package/src/core/builtin/threads.ts +37 -0
  57. package/src/core/config/agent-team.ts +43 -0
  58. package/src/core/config/config.ts +50 -59
  59. package/src/core/config/limits.ts +93 -0
  60. package/src/core/config/ops.ts +34 -0
  61. package/src/core/config/schema.ts +26 -0
  62. package/src/core/contract/channels.ts +20 -0
  63. package/src/core/contract/surface.ts +77 -7
  64. package/src/core/define-roundtable.ts +70 -42
  65. package/src/core/discord/agent-commands.ts +108 -86
  66. package/src/core/discord/agent-panel.ts +11 -2
  67. package/src/core/discord/connection.ts +1 -1
  68. package/src/core/discord/discord-surface.ts +10 -1
  69. package/src/core/discord/dispatch-thread-host.ts +1 -1
  70. package/src/core/domain/conversation.ts +24 -0
  71. package/src/core/holds.ts +221 -15
  72. package/src/core/host-registration.ts +2 -1
  73. package/src/core/http/listeners.ts +63 -3
  74. package/src/core/i18n/agent-panel.ts +14 -21
  75. package/src/core/interactions/prompts.ts +12 -0
  76. package/src/core/modes/autonomy.ts +23 -0
  77. package/src/core/modes/conversation-modes.ts +213 -0
  78. package/src/core/modes/modes-plugin.ts +24 -0
  79. package/src/core/modules/delegation/delegator.ts +4 -4
  80. package/src/core/modules/host-shell/shell-arithmetic.ts +81 -0
  81. package/src/core/modules/host-shell/shell-lexer-types.ts +53 -0
  82. package/src/core/modules/host-shell/shell-lexer.ts +493 -0
  83. package/src/core/modules/host-shell/shell-paths.ts +85 -4
  84. package/src/core/modules/host-shell/shell-policy.ts +341 -332
  85. package/src/core/modules/host-shell/shell-programs.ts +298 -0
  86. package/src/core/modules/host-shell/shell-quoting.ts +237 -0
  87. package/src/core/modules/host-shell/shell-scripts.ts +114 -0
  88. package/src/core/modules/host-shell/shell-wrappers.ts +104 -0
  89. package/src/core/modules/schedules/precheck-tools.ts +17 -0
  90. package/src/core/modules/schedules/schedules.ts +9 -3
  91. package/src/core/plugin.ts +8 -1
  92. package/src/core/presence/direct-channels.ts +30 -0
  93. package/src/core/presentation/reply-body.ts +25 -0
  94. package/src/core/registry/contributions.ts +31 -7
  95. package/src/core/registry/providers.ts +1 -1
  96. package/src/core/routing/conversation-turns.ts +2 -15
  97. package/src/core/routing/surface-port.ts +5 -1
  98. package/src/core/runtime/extensions/approval-card.ts +1 -5
  99. package/src/core/runtime/extensions/approval-fields.ts +3 -7
  100. package/src/core/runtime/extensions/confirmation-gate-extension.ts +13 -2
  101. package/src/core/runtime/extensions/confirmation-gate.ts +41 -40
  102. package/src/core/runtime/extensions/gate-refusals.ts +23 -0
  103. package/src/core/runtime/extensions/held-calls.ts +16 -1
  104. package/src/core/runtime/extensions/hold-describer.ts +58 -8
  105. package/src/core/runtime/extensions/hold-lookups.ts +19 -19
  106. package/src/core/runtime/extensions/yolo.ts +105 -0
  107. package/src/core/runtime/pi-agent-runtime.ts +3 -5
  108. package/src/core/runtime/runtime-plugin.ts +42 -1
  109. package/src/core/runtime/runtime-types.ts +11 -0
  110. package/src/core/runtime/turn-budget.ts +32 -5
  111. package/src/core/runtime/turn-limits.ts +14 -3
  112. package/src/core/services.ts +61 -9
  113. package/src/core/shared/attachment-reader.ts +6 -0
  114. package/src/core/shared/unix-server.ts +10 -1
  115. package/src/core/testing/modules.ts +12 -8
  116. package/src/core/testing/surface-threads.ts +58 -0
  117. package/src/core/testing/thread-host.ts +17 -5
  118. package/src/core/threads/dispatch-threads.ts +299 -0
  119. package/src/core/threads/host-threads.ts +19 -0
  120. package/src/core/tool-set.snapshot.json +5 -0
  121. package/src/index.ts +27 -1
  122. package/src/kit/characters.ts +5 -0
  123. package/src/kit/index.ts +2 -0
  124. package/src/kit/shell.ts +1 -0
  125. package/src/kit/support.ts +1 -1
  126. package/src/kit/threads.ts +1 -1
  127. package/src/testing.ts +4 -0
  128. package/templates/agents.ts +1 -1
  129. package/src/core/discord/dispatch-threads.ts +0 -194
@@ -0,0 +1,1055 @@
1
+ import type {
2
+ CharacterColors,
3
+ CharacterSpec,
4
+ Hex,
5
+ PaletteName,
6
+ } from "./spec.ts";
7
+
8
+ /** Freeze a value and everything reachable from it, so a shared catalog cannot be edited. */
9
+ function deepFreeze<T>(value: T): T {
10
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
11
+ Object.freeze(value);
12
+ for (const child of Object.values(value)) deepFreeze(child);
13
+ }
14
+ return value;
15
+ }
16
+
17
+ export const CLASS_IDS = [
18
+ "wizard",
19
+ "knight",
20
+ "scholar",
21
+ "smith",
22
+ "ranger",
23
+ "bard",
24
+ "alchemist",
25
+ "healer",
26
+ "steward",
27
+ "navigator",
28
+ "seer",
29
+ "scribe",
30
+ "engineer",
31
+ "druid",
32
+ "innkeeper",
33
+ "sentinel",
34
+ "envoy",
35
+ "rogue",
36
+ "monk",
37
+ "falconer",
38
+ "shipwright",
39
+ "jester",
40
+ "paladin",
41
+ "archivist",
42
+ ] as const;
43
+ export type ClassId = (typeof CLASS_IDS)[number];
44
+
45
+ export type OutfitId =
46
+ | "robe"
47
+ | "scholar"
48
+ | "armor"
49
+ | "plate"
50
+ | "apron"
51
+ | "chef"
52
+ | "cloak"
53
+ | "tunic"
54
+ | "coat"
55
+ | "overalls"
56
+ | "vest"
57
+ | "habit"
58
+ | "surplice"
59
+ | "motley"
60
+ | "sailor";
61
+ export const OUTFIT_IDS: readonly OutfitId[] = [
62
+ "robe",
63
+ "scholar",
64
+ "armor",
65
+ "plate",
66
+ "apron",
67
+ "chef",
68
+ "cloak",
69
+ "tunic",
70
+ "coat",
71
+ "overalls",
72
+ "vest",
73
+ "habit",
74
+ "surplice",
75
+ "motley",
76
+ "sailor",
77
+ ];
78
+
79
+ export type HatId =
80
+ | "none"
81
+ | "wizard"
82
+ | "helm"
83
+ | "mortar"
84
+ | "goggcap"
85
+ | "hood"
86
+ | "beret"
87
+ | "goggles"
88
+ | "coif"
89
+ | "tallcap"
90
+ | "tricorn"
91
+ | "turban"
92
+ | "softcap"
93
+ | "hardhat"
94
+ | "wreath"
95
+ | "toque"
96
+ | "kettle"
97
+ | "cavalier"
98
+ | "cowl"
99
+ | "headband"
100
+ | "fcap"
101
+ | "sailor"
102
+ | "jester"
103
+ | "winghelm";
104
+ export const HAT_IDS: readonly HatId[] = [
105
+ "none",
106
+ "wizard",
107
+ "helm",
108
+ "mortar",
109
+ "goggcap",
110
+ "hood",
111
+ "beret",
112
+ "goggles",
113
+ "coif",
114
+ "tallcap",
115
+ "tricorn",
116
+ "turban",
117
+ "softcap",
118
+ "hardhat",
119
+ "wreath",
120
+ "toque",
121
+ "kettle",
122
+ "cavalier",
123
+ "cowl",
124
+ "headband",
125
+ "fcap",
126
+ "sailor",
127
+ "jester",
128
+ "winghelm",
129
+ ];
130
+
131
+ export type PropId =
132
+ | "staff"
133
+ | "shield"
134
+ | "scroll"
135
+ | "hammer"
136
+ | "bow"
137
+ | "lute"
138
+ | "flask"
139
+ | "quill"
140
+ | "tome"
141
+ | "bell"
142
+ | "keys"
143
+ | "map"
144
+ | "telescope"
145
+ | "wrench"
146
+ | "spade"
147
+ | "ladle"
148
+ | "lantern"
149
+ | "seal"
150
+ | "dagger"
151
+ | "beads"
152
+ | "bird"
153
+ | "anchor"
154
+ | "marotte"
155
+ | "sword";
156
+ export const PROP_IDS: readonly PropId[] = [
157
+ "staff",
158
+ "shield",
159
+ "scroll",
160
+ "hammer",
161
+ "bow",
162
+ "lute",
163
+ "flask",
164
+ "quill",
165
+ "tome",
166
+ "bell",
167
+ "keys",
168
+ "map",
169
+ "telescope",
170
+ "wrench",
171
+ "spade",
172
+ "ladle",
173
+ "lantern",
174
+ "seal",
175
+ "dagger",
176
+ "beads",
177
+ "bird",
178
+ "anchor",
179
+ "marotte",
180
+ "sword",
181
+ ];
182
+
183
+ export type HairId =
184
+ | "none"
185
+ | "short"
186
+ | "bob"
187
+ | "long"
188
+ | "bun"
189
+ | "curly"
190
+ | "ponytail"
191
+ | "braid";
192
+ export const HAIR_IDS: readonly HairId[] = [
193
+ "none",
194
+ "short",
195
+ "bob",
196
+ "long",
197
+ "bun",
198
+ "curly",
199
+ "ponytail",
200
+ "braid",
201
+ ];
202
+
203
+ export type BeardId = "full" | "mustache" | "goatee";
204
+ const BEARD_IDS: readonly BeardId[] = ["full", "mustache", "goatee"];
205
+ export const BEARD_CHOICES: readonly (BeardId | "none")[] = [
206
+ ...BEARD_IDS,
207
+ "none",
208
+ ];
209
+
210
+ export type AccessoryId = "glasses" | "freckles" | "scar";
211
+ const ACCESSORY_IDS: readonly AccessoryId[] = ["glasses", "freckles", "scar"];
212
+ export const ACCESSORY_CHOICES: readonly (AccessoryId | "none")[] = [
213
+ ...ACCESSORY_IDS,
214
+ "none",
215
+ ];
216
+
217
+ export const BUILDS: readonly CharacterSpec["build"][] = [
218
+ "slim",
219
+ "regular",
220
+ "stout",
221
+ ];
222
+
223
+ export const SKIN_INDEXES: readonly CharacterSpec["skin"][] = [
224
+ 0, 1, 2, 3, 4, 5,
225
+ ];
226
+
227
+ export const EXPRESSIONS = [
228
+ "neutral",
229
+ "happy",
230
+ "thinking",
231
+ "concerned",
232
+ "apologetic",
233
+ "surprised",
234
+ "proud",
235
+ "amused",
236
+ "curious",
237
+ "sympathetic",
238
+ "playful",
239
+ "determined",
240
+ "sleepy",
241
+ ] as const;
242
+ export type Expression = (typeof EXPRESSIONS)[number];
243
+
244
+ export const AVATAR_STATES = [
245
+ "idle",
246
+ "thinking",
247
+ "working",
248
+ "waiting",
249
+ "done",
250
+ "error",
251
+ "sleepy",
252
+ ] as const;
253
+ export type AvatarState = (typeof AVATAR_STATES)[number];
254
+
255
+ export const STATE_EXPRESSION: Readonly<Record<AvatarState, Expression>> =
256
+ deepFreeze({
257
+ idle: "neutral",
258
+ thinking: "thinking",
259
+ working: "determined",
260
+ waiting: "curious",
261
+ done: "proud",
262
+ error: "apologetic",
263
+ sleepy: "sleepy",
264
+ });
265
+
266
+ /** Heraldic palettes: the field (also the agent accent), a secondary tincture and the metal trim. */
267
+ const PALETTES: Record<PaletteName, CharacterColors> = {
268
+ azure: { primary: "#3b6fd8", secondary: "#eef2ff", trim: "#f0c04a" },
269
+ gules: { primary: "#d8473d", secondary: "#fff1e4", trim: "#f0c04a" },
270
+ vert: { primary: "#2f9e6b", secondary: "#eefbea", trim: "#f0c04a" },
271
+ purpure: { primary: "#7d52cc", secondary: "#f1e9ff", trim: "#f0c04a" },
272
+ amber: { primary: "#e2a02a", secondary: "#fff6dc", trim: "#d5dbe8" },
273
+ sable: { primary: "#454a5c", secondary: "#e9ecf4", trim: "#f0c04a" },
274
+ teal: { primary: "#1f9aa6", secondary: "#e6fbfa", trim: "#f0c04a" },
275
+ rose: { primary: "#d6507f", secondary: "#ffeef3", trim: "#d5dbe8" },
276
+ };
277
+
278
+ /** Skin tones, light to dark. */
279
+ const SKINS: readonly Hex[] = [
280
+ "#f7d6b8",
281
+ "#eab98c",
282
+ "#d4a070",
283
+ "#b9784c",
284
+ "#8e5b3c",
285
+ "#5c3a26",
286
+ ];
287
+
288
+ /** Hair swatches; a spec may carry any other hex. */
289
+ const HAIR_COLORS: readonly Hex[] = [
290
+ "#2b2233",
291
+ "#6a4a33",
292
+ "#b0562f",
293
+ "#e0b45a",
294
+ "#aeb4c3",
295
+ "#f1f3fa",
296
+ ];
297
+
298
+ type ClassPreset = Omit<CharacterSpec, "v" | "class">;
299
+
300
+ function preset(
301
+ fields: Omit<ClassPreset, "colors" | "palette"> & { palette: PaletteName },
302
+ ): ClassPreset {
303
+ const { palette, ...rest } = fields;
304
+ return { ...rest, colors: { ...PALETTES[palette] }, palette };
305
+ }
306
+
307
+ interface ClassEntry {
308
+ label: string;
309
+ /** The agent jobs the class suits. */
310
+ jobs: string;
311
+ /** English and zh-TW words that suggest the class from an agent's name and prompt. */
312
+ keywords: readonly string[];
313
+ preset: ClassPreset;
314
+ }
315
+
316
+ const CLASSES: Record<ClassId, ClassEntry> = {
317
+ wizard: {
318
+ label: "Wizard",
319
+ jobs: "coordinator, planner, main assistant",
320
+ keywords: [
321
+ "coordinat",
322
+ "orchestrat",
323
+ "lead",
324
+ "chief",
325
+ "manager",
326
+ "協調",
327
+ "統籌",
328
+ "總管",
329
+ "主管",
330
+ ],
331
+ preset: preset({
332
+ outfit: "robe",
333
+ hat: "wizard",
334
+ prop: "staff",
335
+ hair: "none",
336
+ beard: "full",
337
+ accessory: "none",
338
+ build: "regular",
339
+ skin: 0,
340
+ hairColor: "#f1f3fa",
341
+ palette: "azure",
342
+ }),
343
+ },
344
+ knight: {
345
+ label: "Knight",
346
+ jobs: "reviewer, QA gate, guardian",
347
+ keywords: [
348
+ "review",
349
+ "qa",
350
+ "quality",
351
+ "gate",
352
+ "lint",
353
+ "guardian",
354
+ "審查",
355
+ "審核",
356
+ "把關",
357
+ "品質",
358
+ ],
359
+ preset: preset({
360
+ outfit: "armor",
361
+ hat: "helm",
362
+ prop: "shield",
363
+ hair: "short",
364
+ beard: "none",
365
+ accessory: "none",
366
+ build: "regular",
367
+ skin: 1,
368
+ hairColor: "#6a4a33",
369
+ palette: "gules",
370
+ }),
371
+ },
372
+ scholar: {
373
+ label: "Scholar",
374
+ jobs: "researcher, literature review",
375
+ keywords: [
376
+ "research",
377
+ "literature",
378
+ "paper",
379
+ "study",
380
+ "survey",
381
+ "academic",
382
+ "研究",
383
+ "文獻",
384
+ "論文",
385
+ "學者",
386
+ ],
387
+ preset: preset({
388
+ outfit: "scholar",
389
+ hat: "mortar",
390
+ prop: "scroll",
391
+ hair: "bun",
392
+ beard: "none",
393
+ accessory: "glasses",
394
+ build: "slim",
395
+ skin: 2,
396
+ hairColor: "#2b2233",
397
+ palette: "purpure",
398
+ }),
399
+ },
400
+ smith: {
401
+ label: "Smith",
402
+ jobs: "coder, builder, refactorer",
403
+ keywords: [
404
+ "coder",
405
+ "coding",
406
+ "code",
407
+ "builder",
408
+ "implement",
409
+ "develop",
410
+ "refactor",
411
+ "software",
412
+ "程式",
413
+ "開發",
414
+ "實作",
415
+ "重構",
416
+ ],
417
+ preset: preset({
418
+ outfit: "apron",
419
+ hat: "goggcap",
420
+ prop: "hammer",
421
+ hair: "short",
422
+ beard: "none",
423
+ accessory: "none",
424
+ build: "stout",
425
+ skin: 3,
426
+ hairColor: "#7a4a2a",
427
+ palette: "amber",
428
+ }),
429
+ },
430
+ ranger: {
431
+ label: "Ranger",
432
+ jobs: "scout, web search, crawler",
433
+ keywords: [
434
+ "scout",
435
+ "search",
436
+ "crawl",
437
+ "explore",
438
+ "browse",
439
+ "web",
440
+ "搜尋",
441
+ "爬蟲",
442
+ "偵查",
443
+ "探索",
444
+ ],
445
+ preset: preset({
446
+ outfit: "cloak",
447
+ hat: "hood",
448
+ prop: "bow",
449
+ hair: "none",
450
+ beard: "none",
451
+ accessory: "freckles",
452
+ build: "slim",
453
+ skin: 1,
454
+ hairColor: "#a8683a",
455
+ palette: "vert",
456
+ }),
457
+ },
458
+ bard: {
459
+ label: "Bard",
460
+ jobs: "writer, announcer, copywriter",
461
+ keywords: [
462
+ "writer",
463
+ "write",
464
+ "copywrit",
465
+ "announce",
466
+ "content",
467
+ "blog",
468
+ "story",
469
+ "poet",
470
+ "寫作",
471
+ "文案",
472
+ "文章",
473
+ "公告",
474
+ ],
475
+ preset: preset({
476
+ outfit: "tunic",
477
+ hat: "beret",
478
+ prop: "lute",
479
+ hair: "long",
480
+ beard: "none",
481
+ accessory: "none",
482
+ build: "regular",
483
+ skin: 4,
484
+ hairColor: "#c0453d",
485
+ palette: "rose",
486
+ }),
487
+ },
488
+ alchemist: {
489
+ label: "Alchemist",
490
+ jobs: "data analyst, ETL, transformer",
491
+ keywords: [
492
+ "analyst",
493
+ "data",
494
+ "etl",
495
+ "transform",
496
+ "convert",
497
+ "spreadsheet",
498
+ "資料",
499
+ "數據",
500
+ "轉換",
501
+ "分析師",
502
+ ],
503
+ preset: preset({
504
+ outfit: "coat",
505
+ hat: "goggles",
506
+ prop: "flask",
507
+ hair: "curly",
508
+ beard: "none",
509
+ accessory: "none",
510
+ build: "regular",
511
+ skin: 5,
512
+ hairColor: "#2b2233",
513
+ palette: "teal",
514
+ }),
515
+ },
516
+ healer: {
517
+ label: "Healer",
518
+ jobs: "debugger, fixer, support",
519
+ keywords: [
520
+ "debug",
521
+ "fix",
522
+ "doctor",
523
+ "heal",
524
+ "bug",
525
+ "repair",
526
+ "triage",
527
+ "support",
528
+ "醫",
529
+ "修",
530
+ "除錯",
531
+ "診斷",
532
+ ],
533
+ preset: preset({
534
+ outfit: "surplice",
535
+ hat: "coif",
536
+ prop: "bell",
537
+ hair: "none",
538
+ beard: "none",
539
+ accessory: "none",
540
+ build: "stout",
541
+ skin: 5,
542
+ hairColor: "#2b2233",
543
+ palette: "rose",
544
+ }),
545
+ },
546
+ steward: {
547
+ label: "Steward",
548
+ jobs: "ops, billing, access keys",
549
+ keywords: [
550
+ "ops",
551
+ "billing",
552
+ "admin",
553
+ "account",
554
+ "access",
555
+ "finance",
556
+ "invoice",
557
+ "procure",
558
+ "帳務",
559
+ "財務",
560
+ "營運",
561
+ "請款",
562
+ "管理",
563
+ ],
564
+ preset: preset({
565
+ outfit: "vest",
566
+ hat: "tallcap",
567
+ prop: "keys",
568
+ hair: "short",
569
+ beard: "mustache",
570
+ accessory: "none",
571
+ build: "stout",
572
+ skin: 0,
573
+ hairColor: "#8a8f9c",
574
+ palette: "sable",
575
+ }),
576
+ },
577
+ navigator: {
578
+ label: "Navigator",
579
+ jobs: "planner, routing, roadmap",
580
+ keywords: [
581
+ "planner",
582
+ "planning",
583
+ "roadmap",
584
+ "route",
585
+ "routing",
586
+ "navigat",
587
+ "itinerary",
588
+ "規劃",
589
+ "路線",
590
+ "導航",
591
+ "行程",
592
+ ],
593
+ preset: preset({
594
+ outfit: "coat",
595
+ hat: "tricorn",
596
+ prop: "map",
597
+ hair: "ponytail",
598
+ beard: "none",
599
+ accessory: "none",
600
+ build: "slim",
601
+ skin: 2,
602
+ hairColor: "#6a4a33",
603
+ palette: "azure",
604
+ }),
605
+ },
606
+ seer: {
607
+ label: "Seer",
608
+ jobs: "forecaster, monitoring, analytics",
609
+ keywords: [
610
+ "forecast",
611
+ "monitor",
612
+ "predict",
613
+ "analytics",
614
+ "metric",
615
+ "observab",
616
+ "trend",
617
+ "預測",
618
+ "監控",
619
+ "觀測",
620
+ "趨勢",
621
+ ],
622
+ preset: preset({
623
+ outfit: "habit",
624
+ hat: "turban",
625
+ prop: "telescope",
626
+ hair: "none",
627
+ beard: "none",
628
+ accessory: "none",
629
+ build: "slim",
630
+ skin: 3,
631
+ hairColor: "#2b2233",
632
+ palette: "purpure",
633
+ }),
634
+ },
635
+ scribe: {
636
+ label: "Scribe",
637
+ jobs: "documentation, notes, minutes",
638
+ keywords: [
639
+ "document",
640
+ "docs",
641
+ "notes",
642
+ "minutes",
643
+ "transcri",
644
+ "changelog",
645
+ "文件",
646
+ "記錄",
647
+ "紀錄",
648
+ "筆記",
649
+ "會議",
650
+ ],
651
+ preset: preset({
652
+ outfit: "scholar",
653
+ hat: "softcap",
654
+ prop: "quill",
655
+ hair: "short",
656
+ beard: "none",
657
+ accessory: "glasses",
658
+ build: "regular",
659
+ skin: 1,
660
+ hairColor: "#3a2f45",
661
+ palette: "sable",
662
+ }),
663
+ },
664
+ engineer: {
665
+ label: "Engineer",
666
+ jobs: "devops, infra, CI",
667
+ keywords: [
668
+ "infra",
669
+ "devops",
670
+ "ci",
671
+ "sre",
672
+ "platform",
673
+ "kubernetes",
674
+ "server",
675
+ "cluster",
676
+ "維運",
677
+ "運維",
678
+ "基礎設施",
679
+ "伺服器",
680
+ ],
681
+ preset: preset({
682
+ outfit: "overalls",
683
+ hat: "hardhat",
684
+ prop: "wrench",
685
+ hair: "braid",
686
+ beard: "none",
687
+ accessory: "none",
688
+ build: "regular",
689
+ skin: 4,
690
+ hairColor: "#2b2233",
691
+ palette: "amber",
692
+ }),
693
+ },
694
+ druid: {
695
+ label: "Druid",
696
+ jobs: "cleanup, data hygiene, maintenance",
697
+ keywords: [
698
+ "cleanup",
699
+ "clean",
700
+ "hygiene",
701
+ "maintenance",
702
+ "garbage",
703
+ "prune",
704
+ "tidy",
705
+ "清理",
706
+ "整理",
707
+ "維護",
708
+ "保養",
709
+ ],
710
+ preset: preset({
711
+ outfit: "cloak",
712
+ hat: "wreath",
713
+ prop: "spade",
714
+ hair: "long",
715
+ beard: "none",
716
+ accessory: "none",
717
+ build: "regular",
718
+ skin: 4,
719
+ hairColor: "#6a4a33",
720
+ palette: "vert",
721
+ }),
722
+ },
723
+ innkeeper: {
724
+ label: "Innkeeper",
725
+ jobs: "concierge, onboarding, scheduler",
726
+ keywords: [
727
+ "concierge",
728
+ "onboard",
729
+ "scheduler",
730
+ "schedule",
731
+ "host",
732
+ "welcome",
733
+ "reception",
734
+ "接待",
735
+ "迎賓",
736
+ "排程",
737
+ "新人",
738
+ ],
739
+ preset: preset({
740
+ outfit: "chef",
741
+ hat: "toque",
742
+ prop: "ladle",
743
+ hair: "none",
744
+ beard: "mustache",
745
+ accessory: "none",
746
+ build: "stout",
747
+ skin: 2,
748
+ hairColor: "#2b2233",
749
+ palette: "gules",
750
+ }),
751
+ },
752
+ sentinel: {
753
+ label: "Sentinel",
754
+ jobs: "security, on-call, alerts",
755
+ keywords: [
756
+ "security",
757
+ "alert",
758
+ "incident",
759
+ "oncall",
760
+ "on-call",
761
+ "vulnerab",
762
+ "patrol",
763
+ "資安",
764
+ "安全",
765
+ "告警",
766
+ "警報",
767
+ "值班",
768
+ ],
769
+ preset: preset({
770
+ outfit: "plate",
771
+ hat: "kettle",
772
+ prop: "lantern",
773
+ hair: "none",
774
+ beard: "none",
775
+ accessory: "scar",
776
+ build: "stout",
777
+ skin: 5,
778
+ hairColor: "#2b2233",
779
+ palette: "sable",
780
+ }),
781
+ },
782
+ envoy: {
783
+ label: "Envoy",
784
+ jobs: "email, partner comms, notifications",
785
+ keywords: [
786
+ "email",
787
+ "mail",
788
+ "partner",
789
+ "notif",
790
+ "message",
791
+ "outreach",
792
+ "comms",
793
+ "信件",
794
+ "郵件",
795
+ "通知",
796
+ "聯絡",
797
+ ],
798
+ preset: preset({
799
+ outfit: "tunic",
800
+ hat: "cavalier",
801
+ prop: "seal",
802
+ hair: "bun",
803
+ beard: "none",
804
+ accessory: "none",
805
+ build: "regular",
806
+ skin: 1,
807
+ hairColor: "#aeb4c3",
808
+ palette: "purpure",
809
+ }),
810
+ },
811
+ rogue: {
812
+ label: "Rogue",
813
+ jobs: "pen-tester, auditor, intel",
814
+ keywords: [
815
+ "pentest",
816
+ "pen-test",
817
+ "penetration",
818
+ "auditor",
819
+ "audit",
820
+ "intel",
821
+ "exploit",
822
+ "osint",
823
+ "滲透",
824
+ "稽核",
825
+ "情報",
826
+ "紅隊",
827
+ ],
828
+ preset: preset({
829
+ outfit: "cloak",
830
+ hat: "cowl",
831
+ prop: "dagger",
832
+ hair: "none",
833
+ beard: "none",
834
+ accessory: "scar",
835
+ build: "slim",
836
+ skin: 0,
837
+ hairColor: "#2b2233",
838
+ palette: "sable",
839
+ }),
840
+ },
841
+ monk: {
842
+ label: "Monk",
843
+ jobs: "long-running jobs, batch, patience",
844
+ keywords: [
845
+ "long-running",
846
+ "batch",
847
+ "patient",
848
+ "background",
849
+ "overnight",
850
+ "meditat",
851
+ "cron",
852
+ "長時間",
853
+ "批次",
854
+ "批量",
855
+ "耐心",
856
+ ],
857
+ preset: preset({
858
+ outfit: "habit",
859
+ hat: "headband",
860
+ prop: "beads",
861
+ hair: "none",
862
+ beard: "none",
863
+ accessory: "none",
864
+ build: "regular",
865
+ skin: 3,
866
+ hairColor: "#2b2233",
867
+ palette: "amber",
868
+ }),
869
+ },
870
+ falconer: {
871
+ label: "Falconer",
872
+ jobs: "retrieval, fetch, RAG lookup",
873
+ keywords: [
874
+ "retriev",
875
+ "fetch",
876
+ "rag",
877
+ "lookup",
878
+ "vector",
879
+ "embedding",
880
+ "檢索",
881
+ "擷取",
882
+ "抓取",
883
+ "查詢",
884
+ ],
885
+ preset: preset({
886
+ outfit: "cloak",
887
+ hat: "fcap",
888
+ prop: "bird",
889
+ hair: "short",
890
+ beard: "goatee",
891
+ accessory: "none",
892
+ build: "slim",
893
+ skin: 4,
894
+ hairColor: "#2b2233",
895
+ palette: "vert",
896
+ }),
897
+ },
898
+ shipwright: {
899
+ label: "Shipwright",
900
+ jobs: "release, build pipeline, packaging",
901
+ keywords: [
902
+ "release",
903
+ "ship",
904
+ "packag",
905
+ "publish",
906
+ "deploy",
907
+ "pipeline",
908
+ "發版",
909
+ "發布",
910
+ "打包",
911
+ "上線",
912
+ "部署",
913
+ ],
914
+ preset: preset({
915
+ outfit: "sailor",
916
+ hat: "sailor",
917
+ prop: "anchor",
918
+ hair: "short",
919
+ beard: "goatee",
920
+ accessory: "none",
921
+ build: "stout",
922
+ skin: 2,
923
+ hairColor: "#e0b45a",
924
+ palette: "azure",
925
+ }),
926
+ },
927
+ jester: {
928
+ label: "Jester",
929
+ jobs: "brainstorm, ideation, humor",
930
+ keywords: [
931
+ "brainstorm",
932
+ "ideation",
933
+ "idea",
934
+ "humor",
935
+ "joke",
936
+ "creative",
937
+ "fun",
938
+ "腦力激盪",
939
+ "發想",
940
+ "創意",
941
+ "幽默",
942
+ "點子",
943
+ ],
944
+ preset: preset({
945
+ outfit: "motley",
946
+ hat: "jester",
947
+ prop: "marotte",
948
+ hair: "none",
949
+ beard: "none",
950
+ accessory: "freckles",
951
+ build: "slim",
952
+ skin: 0,
953
+ hairColor: "#b0562f",
954
+ palette: "gules",
955
+ }),
956
+ },
957
+ paladin: {
958
+ label: "Paladin",
959
+ jobs: "compliance, policy, approvals",
960
+ keywords: [
961
+ "compliance",
962
+ "policy",
963
+ "approval",
964
+ "approve",
965
+ "govern",
966
+ "legal",
967
+ "ethic",
968
+ "合規",
969
+ "法遵",
970
+ "核准",
971
+ "政策",
972
+ "規範",
973
+ ],
974
+ preset: preset({
975
+ outfit: "plate",
976
+ hat: "winghelm",
977
+ prop: "sword",
978
+ hair: "none",
979
+ beard: "none",
980
+ accessory: "none",
981
+ build: "regular",
982
+ skin: 5,
983
+ hairColor: "#2b2233",
984
+ palette: "amber",
985
+ }),
986
+ },
987
+ archivist: {
988
+ label: "Archivist",
989
+ jobs: "knowledge base, indexing, memory",
990
+ keywords: [
991
+ "knowledge",
992
+ "archive",
993
+ "index",
994
+ "memory",
995
+ "wiki",
996
+ "catalog",
997
+ "library",
998
+ "知識",
999
+ "索引",
1000
+ "記憶",
1001
+ "歸檔",
1002
+ "典藏",
1003
+ ],
1004
+ preset: preset({
1005
+ outfit: "scholar",
1006
+ hat: "none",
1007
+ prop: "tome",
1008
+ hair: "bun",
1009
+ beard: "none",
1010
+ accessory: "glasses",
1011
+ build: "regular",
1012
+ skin: 2,
1013
+ hairColor: "#e4e7f0",
1014
+ palette: "teal",
1015
+ }),
1016
+ },
1017
+ };
1018
+
1019
+ export const CATALOG: Readonly<{
1020
+ classes: Readonly<
1021
+ Record<
1022
+ ClassId,
1023
+ Readonly<{
1024
+ label: string;
1025
+ /** The agent jobs the class suits. */
1026
+ jobs: string;
1027
+ /** English and zh-TW words that suggest the class from an agent's name and prompt. */
1028
+ keywords: readonly string[];
1029
+ preset: Omit<CharacterSpec, "v" | "class">;
1030
+ }>
1031
+ >
1032
+ >;
1033
+ outfits: readonly OutfitId[];
1034
+ hats: readonly HatId[];
1035
+ props: readonly PropId[];
1036
+ hair: readonly HairId[];
1037
+ beards: readonly BeardId[];
1038
+ accessories: readonly AccessoryId[];
1039
+ palettes: Readonly<Record<PaletteName, CharacterColors>>;
1040
+ skins: readonly Hex[];
1041
+ hairColors: readonly Hex[];
1042
+ }> = deepFreeze({
1043
+ classes: CLASSES,
1044
+ outfits: OUTFIT_IDS,
1045
+ hats: HAT_IDS,
1046
+ props: PROP_IDS,
1047
+ hair: HAIR_IDS,
1048
+ beards: BEARD_IDS,
1049
+ accessories: ACCESSORY_IDS,
1050
+ palettes: PALETTES,
1051
+ skins: SKINS,
1052
+ hairColors: HAIR_COLORS,
1053
+ });
1054
+
1055
+ export const PALETTE_NAMES = Object.keys(PALETTES) as PaletteName[];