@openacp/cli 0.6.1 → 0.6.3

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 (101) hide show
  1. package/dist/{admin-IKPS5PFC.js → admin-3ZHEO5VP.js} +8 -4
  2. package/dist/{agent-catalog-T5ECPEDA.js → agent-catalog-IVU2KANH.js} +2 -2
  3. package/dist/{agents-55NX3DHM.js → agents-SXIY4IEF.js} +2 -2
  4. package/dist/{chunk-H7ZMPBZC.js → chunk-3KGRVAEV.js} +1 -1
  5. package/dist/chunk-3KGRVAEV.js.map +1 -0
  6. package/dist/{chunk-GINCOFNW.js → chunk-6LSFRNHE.js} +2 -2
  7. package/dist/chunk-6LSFRNHE.js.map +1 -0
  8. package/dist/{chunk-UB7XUO7C.js → chunk-AVCHZESZ.js} +3 -3
  9. package/dist/{chunk-J6X5SW6O.js → chunk-CKOK7JW6.js} +3 -2
  10. package/dist/{chunk-J6X5SW6O.js.map → chunk-CKOK7JW6.js.map} +1 -1
  11. package/dist/{chunk-4LFDEW22.js → chunk-EWYNCHUH.js} +33 -20
  12. package/dist/chunk-EWYNCHUH.js.map +1 -0
  13. package/dist/{chunk-4TR5Y3MP.js → chunk-F3AICYO4.js} +39 -1
  14. package/dist/chunk-F3AICYO4.js.map +1 -0
  15. package/dist/{chunk-LGQYTK55.js → chunk-FMWSVLRM.js} +31 -2
  16. package/dist/chunk-FMWSVLRM.js.map +1 -0
  17. package/dist/{chunk-AKIU4JBF.js → chunk-FZ5BIWG5.js} +6 -6
  18. package/dist/chunk-FZ5BIWG5.js.map +1 -0
  19. package/dist/{chunk-2KJC3ILH.js → chunk-G3OHCXZG.js} +34 -24
  20. package/dist/chunk-G3OHCXZG.js.map +1 -0
  21. package/dist/{chunk-R3UJUOXI.js → chunk-HP2IJYCA.js} +1817 -1015
  22. package/dist/chunk-HP2IJYCA.js.map +1 -0
  23. package/dist/chunk-IER5UCY7.js +298 -0
  24. package/dist/chunk-IER5UCY7.js.map +1 -0
  25. package/dist/{chunk-TOZQ3JFN.js → chunk-KO5RL7MZ.js} +2 -2
  26. package/dist/{chunk-7G5QKLLF.js → chunk-NXEQXRQR.js} +53 -9
  27. package/dist/chunk-NXEQXRQR.js.map +1 -0
  28. package/dist/{chunk-ZCHNAM3B.js → chunk-OHR6SBMC.js} +3 -3
  29. package/dist/chunk-PWFPTG5X.js +101 -0
  30. package/dist/chunk-PWFPTG5X.js.map +1 -0
  31. package/dist/{chunk-IMILOCR5.js → chunk-TMCQZAXN.js} +2 -2
  32. package/dist/chunk-TMCQZAXN.js.map +1 -0
  33. package/dist/{chunk-T22OLSET.js → chunk-TTDSLV35.js} +1 -1
  34. package/dist/chunk-TTDSLV35.js.map +1 -0
  35. package/dist/cli.js +41 -36
  36. package/dist/cli.js.map +1 -1
  37. package/dist/{config-AK2W3E67.js → config-4YSJ4NCI.js} +2 -2
  38. package/dist/{config-editor-VIA7A72X.js → config-editor-F25HEMGL.js} +4 -4
  39. package/dist/{config-registry-QQOJ2GQP.js → config-registry-7I6GGDOY.js} +2 -2
  40. package/dist/{daemon-G27YZUWB.js → daemon-I6XMRQ6P.js} +3 -3
  41. package/dist/{discord-2DKRH45T.js → discord-VHCBN3JJ.js} +226 -172
  42. package/dist/discord-VHCBN3JJ.js.map +1 -0
  43. package/dist/{doctor-CHCYUTV5.js → doctor-GPW5ECK6.js} +4 -4
  44. package/dist/doctor-Y3SCSVPI.js +9 -0
  45. package/dist/index.d.ts +176 -90
  46. package/dist/index.js +22 -12
  47. package/dist/install-cloudflared-G2GUKCHA.js +32 -0
  48. package/dist/install-cloudflared-G2GUKCHA.js.map +1 -0
  49. package/dist/install-jq-7QTU7XYY.js +31 -0
  50. package/dist/install-jq-7QTU7XYY.js.map +1 -0
  51. package/dist/{integrate-VOUYBPPZ.js → integrate-O4OCR4SN.js} +23 -11
  52. package/dist/integrate-O4OCR4SN.js.map +1 -0
  53. package/dist/{main-56SPFYW4.js → main-P4X6SAPZ.js} +29 -18
  54. package/dist/main-P4X6SAPZ.js.map +1 -0
  55. package/dist/{new-session-DRRP2J7E.js → new-session-PUNUHGYP.js} +3 -3
  56. package/dist/post-upgrade-6N4JCV5S.js +79 -0
  57. package/dist/post-upgrade-6N4JCV5S.js.map +1 -0
  58. package/dist/{session-FVFLBREJ.js → session-ZMAM67AA.js} +2 -2
  59. package/dist/{settings-LPOLJ6SA.js → settings-OEQEZS5Y.js} +3 -2
  60. package/dist/{setup-IPWJCIJM.js → setup-7YBFKRG7.js} +5 -3
  61. package/dist/{tunnel-service-U6V4HQOO.js → tunnel-service-BMIBHUBK.js} +35 -17
  62. package/dist/tunnel-service-BMIBHUBK.js.map +1 -0
  63. package/package.json +2 -1
  64. package/dist/chunk-2KJC3ILH.js.map +0 -1
  65. package/dist/chunk-4LFDEW22.js.map +0 -1
  66. package/dist/chunk-4TR5Y3MP.js.map +0 -1
  67. package/dist/chunk-7G5QKLLF.js.map +0 -1
  68. package/dist/chunk-AKIU4JBF.js.map +0 -1
  69. package/dist/chunk-GINCOFNW.js.map +0 -1
  70. package/dist/chunk-H7ZMPBZC.js.map +0 -1
  71. package/dist/chunk-IMILOCR5.js.map +0 -1
  72. package/dist/chunk-LGQYTK55.js.map +0 -1
  73. package/dist/chunk-R3UJUOXI.js.map +0 -1
  74. package/dist/chunk-RF3DUYFO.js +0 -103
  75. package/dist/chunk-RF3DUYFO.js.map +0 -1
  76. package/dist/chunk-T22OLSET.js.map +0 -1
  77. package/dist/chunk-THBR6OXH.js +0 -62
  78. package/dist/chunk-THBR6OXH.js.map +0 -1
  79. package/dist/discord-2DKRH45T.js.map +0 -1
  80. package/dist/doctor-AN6AZ3PF.js +0 -9
  81. package/dist/install-cloudflared-BTGUD7SW.js +0 -8
  82. package/dist/integrate-VOUYBPPZ.js.map +0 -1
  83. package/dist/main-56SPFYW4.js.map +0 -1
  84. package/dist/setup-IPWJCIJM.js.map +0 -1
  85. package/dist/tunnel-service-U6V4HQOO.js.map +0 -1
  86. /package/dist/{admin-IKPS5PFC.js.map → admin-3ZHEO5VP.js.map} +0 -0
  87. /package/dist/{agent-catalog-T5ECPEDA.js.map → agent-catalog-IVU2KANH.js.map} +0 -0
  88. /package/dist/{agents-55NX3DHM.js.map → agents-SXIY4IEF.js.map} +0 -0
  89. /package/dist/{chunk-UB7XUO7C.js.map → chunk-AVCHZESZ.js.map} +0 -0
  90. /package/dist/{chunk-TOZQ3JFN.js.map → chunk-KO5RL7MZ.js.map} +0 -0
  91. /package/dist/{chunk-ZCHNAM3B.js.map → chunk-OHR6SBMC.js.map} +0 -0
  92. /package/dist/{config-AK2W3E67.js.map → config-4YSJ4NCI.js.map} +0 -0
  93. /package/dist/{config-editor-VIA7A72X.js.map → config-editor-F25HEMGL.js.map} +0 -0
  94. /package/dist/{config-registry-QQOJ2GQP.js.map → config-registry-7I6GGDOY.js.map} +0 -0
  95. /package/dist/{daemon-G27YZUWB.js.map → daemon-I6XMRQ6P.js.map} +0 -0
  96. /package/dist/{doctor-AN6AZ3PF.js.map → doctor-GPW5ECK6.js.map} +0 -0
  97. /package/dist/{doctor-CHCYUTV5.js.map → doctor-Y3SCSVPI.js.map} +0 -0
  98. /package/dist/{install-cloudflared-BTGUD7SW.js.map → new-session-PUNUHGYP.js.map} +0 -0
  99. /package/dist/{new-session-DRRP2J7E.js.map → session-ZMAM67AA.js.map} +0 -0
  100. /package/dist/{session-FVFLBREJ.js.map → settings-OEQEZS5Y.js.map} +0 -0
  101. /package/dist/{settings-LPOLJ6SA.js.map → setup-7YBFKRG7.js.map} +0 -0
@@ -1,53 +1,57 @@
1
+ import {
2
+ handleNew,
3
+ handleNewChat,
4
+ handleNewSessionButton
5
+ } from "./chunk-FZ5BIWG5.js";
6
+ import {
7
+ handleDangerous,
8
+ handleDangerousButton,
9
+ handleRestart,
10
+ handleTTS,
11
+ handleTTSButton,
12
+ handleUpdate
13
+ } from "./chunk-NXEQXRQR.js";
1
14
  import {
2
15
  handleCancel,
3
16
  handleCleanupButton,
4
17
  handleHandoff,
5
18
  handleSessions,
6
19
  handleStatus
7
- } from "./chunk-T22OLSET.js";
20
+ } from "./chunk-TTDSLV35.js";
21
+ import {
22
+ buildDeepLink,
23
+ createSessionThread,
24
+ deleteSessionThread,
25
+ ensureForums,
26
+ ensureUnarchived,
27
+ renameSessionThread
28
+ } from "./chunk-SM3G6UAX.js";
8
29
  import {
9
30
  handleAgentButton,
10
31
  handleAgents,
11
32
  handleInstall
12
- } from "./chunk-H7ZMPBZC.js";
33
+ } from "./chunk-3KGRVAEV.js";
13
34
  import {
14
35
  handleSettings,
15
36
  handleSettingsButton
16
- } from "./chunk-THBR6OXH.js";
37
+ } from "./chunk-IER5UCY7.js";
17
38
  import {
18
39
  handleDoctor,
19
40
  handleDoctorButton
20
- } from "./chunk-GINCOFNW.js";
41
+ } from "./chunk-6LSFRNHE.js";
21
42
  import {
22
43
  buildActionKeyboard,
23
44
  detectAction,
24
45
  storeAction
25
46
  } from "./chunk-I7WC6E5S.js";
26
- import {
27
- handleNew,
28
- handleNewChat,
29
- handleNewSessionButton
30
- } from "./chunk-AKIU4JBF.js";
31
- import {
32
- buildDeepLink,
33
- createSessionThread,
34
- deleteSessionThread,
35
- ensureForums,
36
- ensureUnarchived,
37
- renameSessionThread
38
- } from "./chunk-SM3G6UAX.js";
39
- import {
40
- handleDangerous,
41
- handleDangerousButton,
42
- handleRestart,
43
- handleUpdate
44
- } from "./chunk-7G5QKLLF.js";
45
47
  import {
46
48
  ChannelAdapter,
47
- PRODUCT_GUIDE
48
- } from "./chunk-LGQYTK55.js";
49
- import "./chunk-ZCHNAM3B.js";
50
- import "./chunk-4LFDEW22.js";
49
+ PRODUCT_GUIDE,
50
+ dispatchMessage
51
+ } from "./chunk-FMWSVLRM.js";
52
+ import "./chunk-OHR6SBMC.js";
53
+ import "./chunk-F3AICYO4.js";
54
+ import "./chunk-EWYNCHUH.js";
51
55
  import {
52
56
  log
53
57
  } from "./chunk-ESOPMQAY.js";
@@ -421,6 +425,21 @@ var MessageDraft = class {
421
425
  }
422
426
  }
423
427
  }
428
+ async stripPattern(pattern) {
429
+ if (!this.message || !this.buffer) return;
430
+ const stripped = this.buffer.replace(pattern, "").trim();
431
+ if (stripped === this.buffer.trim()) return;
432
+ this.buffer = stripped;
433
+ this.lastSentBuffer = stripped;
434
+ if (!stripped) return;
435
+ try {
436
+ await this.sendQueue.enqueue(
437
+ () => this.message.edit({ content: stripped }),
438
+ { type: "other" }
439
+ );
440
+ } catch {
441
+ }
442
+ }
424
443
  async finalize() {
425
444
  if (this.flushTimer) {
426
445
  clearTimeout(this.flushTimer);
@@ -491,6 +510,9 @@ var DraftManager = class {
491
510
  hasDraft(sessionId) {
492
511
  return this.drafts.has(sessionId);
493
512
  }
513
+ getDraft(sessionId) {
514
+ return this.drafts.get(sessionId);
515
+ }
494
516
  appendText(sessionId, text) {
495
517
  this.textBuffers.set(sessionId, (this.textBuffers.get(sessionId) ?? "") + text);
496
518
  }
@@ -816,8 +838,10 @@ var SkillCommandManager = class {
816
838
  const record = this.sessionManager.getSessionRecord(sessionId);
817
839
  if (record) {
818
840
  const platform = record.platform;
819
- const { skillMsgId: _removed, ...rest } = platform;
820
- await this.sessionManager.patchRecord(sessionId, { platform: rest });
841
+ if (platform && typeof platform === "object" && "threadId" in platform) {
842
+ const { skillMsgId: _removed, ...rest } = platform;
843
+ await this.sessionManager.patchRecord(sessionId, { platform: rest });
844
+ }
821
845
  }
822
846
  }
823
847
  };
@@ -930,6 +954,7 @@ function buildMenuKeyboard() {
930
954
  new ButtonBuilder2().setCustomId("m:integrate").setLabel("\u{1F517} Integrate").setStyle(ButtonStyle2.Secondary)
931
955
  );
932
956
  const row3 = new ActionRowBuilder2().addComponents(
957
+ new ButtonBuilder2().setCustomId("m:tts").setLabel("\u{1F50A} TTS").setStyle(ButtonStyle2.Secondary),
933
958
  new ButtonBuilder2().setCustomId("m:restart").setLabel("\u{1F504} Restart").setStyle(ButtonStyle2.Secondary),
934
959
  new ButtonBuilder2().setCustomId("m:update").setLabel("\u2B06\uFE0F Update").setStyle(ButtonStyle2.Secondary),
935
960
  new ButtonBuilder2().setCustomId("m:help").setLabel("\u2753 Help").setStyle(ButtonStyle2.Secondary),
@@ -970,6 +995,7 @@ Each session gets its own forum thread \u2014 chat there to work with the agent.
970
995
 
971
996
  \u{1F512} **Session Options**
972
997
  \`/dangerous\` \u2014 Toggle dangerous mode (auto-approve permissions)
998
+ \`/tts\` \u2014 Toggle Text to Speech (on/off/next message)
973
999
  \`/handoff\` \u2014 Continue session in your terminal
974
1000
  \`/clear\` \u2014 Clear assistant session history
975
1001
 
@@ -980,12 +1006,12 @@ Each session gets its own forum thread \u2014 chat there to work with the agent.
980
1006
  }
981
1007
  async function handleClear(interaction, adapter) {
982
1008
  await interaction.deferReply({ ephemeral: true });
983
- if (!adapter.assistant) {
1009
+ if (!adapter.getAssistantSessionId()) {
984
1010
  await interaction.editReply("\u26A0\uFE0F Assistant is not available.");
985
1011
  return;
986
1012
  }
987
1013
  try {
988
- await adapter.assistant.respawn();
1014
+ await adapter.respawnAssistant();
989
1015
  await interaction.editReply("\u2705 Assistant history cleared.");
990
1016
  } catch (err) {
991
1017
  const message = err instanceof Error ? err.message : String(err);
@@ -1001,12 +1027,12 @@ async function handleMenuButton(interaction, adapter) {
1001
1027
  try {
1002
1028
  switch (customId) {
1003
1029
  case "m:new": {
1004
- const { handleNew: handleNew2 } = await import("./new-session-DRRP2J7E.js");
1030
+ const { handleNew: handleNew2 } = await import("./new-session-PUNUHGYP.js");
1005
1031
  await interaction.followUp({ content: "Use `/new` to create a new session.", ephemeral: true });
1006
1032
  break;
1007
1033
  }
1008
1034
  case "m:sessions": {
1009
- const { handleSessions: handleSessions2 } = await import("./session-FVFLBREJ.js");
1035
+ const { handleSessions: handleSessions2 } = await import("./session-ZMAM67AA.js");
1010
1036
  await showSessionsList(interaction, adapter);
1011
1037
  break;
1012
1038
  }
@@ -1015,12 +1041,12 @@ async function handleMenuButton(interaction, adapter) {
1015
1041
  break;
1016
1042
  }
1017
1043
  case "m:agents": {
1018
- const { showAgentsList } = await import("./agents-55NX3DHM.js");
1044
+ const { showAgentsList } = await import("./agents-SXIY4IEF.js");
1019
1045
  await showAgentsList(interaction, adapter);
1020
1046
  break;
1021
1047
  }
1022
1048
  case "m:settings": {
1023
- const { showSettingsInfo } = await import("./settings-LPOLJ6SA.js");
1049
+ const { showSettingsInfo } = await import("./settings-OEQEZS5Y.js");
1024
1050
  await showSettingsInfo(interaction, adapter);
1025
1051
  break;
1026
1052
  }
@@ -1029,7 +1055,7 @@ async function handleMenuButton(interaction, adapter) {
1029
1055
  break;
1030
1056
  }
1031
1057
  case "m:restart": {
1032
- const { handleRestart: handleRestart2 } = await import("./admin-IKPS5PFC.js");
1058
+ const { handleRestart: handleRestart2 } = await import("./admin-3ZHEO5VP.js");
1033
1059
  if (!adapter.core.requestRestart) {
1034
1060
  await interaction.followUp({ content: "\u26A0\uFE0F Restart not available.", ephemeral: true });
1035
1061
  } else {
@@ -1048,10 +1074,23 @@ async function handleMenuButton(interaction, adapter) {
1048
1074
  break;
1049
1075
  }
1050
1076
  case "m:doctor": {
1051
- const { runDoctorInline } = await import("./doctor-CHCYUTV5.js");
1077
+ const { runDoctorInline } = await import("./doctor-GPW5ECK6.js");
1052
1078
  await runDoctorInline(interaction, adapter);
1053
1079
  break;
1054
1080
  }
1081
+ case "m:tts": {
1082
+ const channelId = interaction.channelId;
1083
+ const session = adapter.core.sessionManager.getSessionByThread("discord", channelId);
1084
+ if (!session) {
1085
+ await interaction.followUp({ content: "\u26A0\uFE0F No active session in this channel. Use `/tts` inside a session thread.", ephemeral: true });
1086
+ } else {
1087
+ const newMode = session.voiceMode === "on" ? "off" : "on";
1088
+ session.setVoiceMode(newMode);
1089
+ const msg = newMode === "on" ? "\u{1F50A} Text to Speech enabled for this session." : "\u{1F507} Text to Speech disabled.";
1090
+ await interaction.followUp({ content: msg, ephemeral: true });
1091
+ }
1092
+ break;
1093
+ }
1055
1094
  default:
1056
1095
  log.warn({ customId }, "[discord-menu] Unhandled menu button");
1057
1096
  }
@@ -1186,6 +1225,9 @@ async function handleSlashCommand(interaction, adapter) {
1186
1225
  case "clear":
1187
1226
  await handleClear(interaction, adapter);
1188
1227
  break;
1228
+ case "tts":
1229
+ await handleTTS(interaction, adapter);
1230
+ break;
1189
1231
  default:
1190
1232
  log.warn({ commandName }, "[discord-router] Unknown slash command");
1191
1233
  if (!interaction.replied && !interaction.deferred) {
@@ -1235,6 +1277,10 @@ async function setupButtonCallbacks(interaction, adapter) {
1235
1277
  await handleDangerousButton(interaction, adapter);
1236
1278
  return;
1237
1279
  }
1280
+ if (customId.startsWith("v:")) {
1281
+ await handleTTSButton(interaction, adapter);
1282
+ return;
1283
+ }
1238
1284
  if (customId.startsWith("m:new:")) {
1239
1285
  await handleNewSessionButton(interaction, adapter);
1240
1286
  return;
@@ -1287,11 +1333,11 @@ async function setupButtonCallbacks(interaction, adapter) {
1287
1333
  }
1288
1334
  }
1289
1335
  async function executeNewSession(interaction, adapter, agentName, workspace) {
1290
- const { executeNewSession: doExecute } = await import("./new-session-DRRP2J7E.js");
1336
+ const { executeNewSession: doExecute } = await import("./new-session-PUNUHGYP.js");
1291
1337
  await doExecute(interaction, adapter, agentName, workspace);
1292
1338
  }
1293
1339
  async function executeCancelSession(interaction, adapter) {
1294
- const { executeCancelSession: doCancel } = await import("./session-FVFLBREJ.js");
1340
+ const { executeCancelSession: doCancel } = await import("./session-ZMAM67AA.js");
1295
1341
  await doCancel(interaction, adapter);
1296
1342
  }
1297
1343
 
@@ -1313,7 +1359,13 @@ var SLASH_COMMANDS = [
1313
1359
  new SlashCommandBuilder().setName("settings").setDescription("Show configuration settings"),
1314
1360
  new SlashCommandBuilder().setName("doctor").setDescription("Run system diagnostics"),
1315
1361
  new SlashCommandBuilder().setName("handoff").setDescription("Generate a terminal resume command for this session"),
1316
- new SlashCommandBuilder().setName("clear").setDescription("Reset the assistant session")
1362
+ new SlashCommandBuilder().setName("clear").setDescription("Reset the assistant session"),
1363
+ new SlashCommandBuilder().setName("tts").setDescription("Toggle Text to Speech for the current session").addStringOption(
1364
+ (o) => o.setName("mode").setDescription("on = persistent, off = disable, empty = next message only").setRequired(false).addChoices(
1365
+ { name: "on", value: "on" },
1366
+ { name: "off", value: "off" }
1367
+ )
1368
+ )
1317
1369
  ];
1318
1370
  async function registerSlashCommands(guild) {
1319
1371
  await guild.commands.set(SLASH_COMMANDS.map((cmd) => cmd.toJSON()));
@@ -1795,148 +1847,158 @@ var DiscordAdapter = class extends ChannelAdapter {
1795
1847
  return null;
1796
1848
  }
1797
1849
  }
1798
- // ─── sendMessage ──────────────────────────────────────────────────────────
1799
- async sendMessage(sessionId, content) {
1800
- if (this.assistantInitializing && this.assistantSession && sessionId === this.assistantSession.id) {
1801
- return;
1802
- }
1803
- const thread = await this.getThread(sessionId);
1804
- if (!thread) return;
1805
- await ensureUnarchived(thread);
1806
- const isAssistant = this.assistantSession != null && sessionId === this.assistantSession.id;
1850
+ // ─── Helper: get or create activity tracker ──────────────────────────────
1851
+ getOrCreateTracker(sessionId, thread) {
1807
1852
  if (!this.sessionTrackers.has(sessionId)) {
1808
1853
  this.sessionTrackers.set(sessionId, new ActivityTracker(thread, this.sendQueue));
1809
1854
  }
1810
- const tracker = this.sessionTrackers.get(sessionId);
1811
- switch (content.type) {
1812
- case "thought": {
1813
- await tracker.onThought();
1814
- break;
1815
- }
1816
- case "text": {
1817
- await tracker.onTextStart();
1818
- const draft = this.draftManager.getOrCreate(sessionId, thread);
1819
- draft.append(content.text);
1820
- this.draftManager.appendText(sessionId, content.text);
1821
- break;
1822
- }
1823
- case "tool_call": {
1824
- await tracker.onToolCall();
1825
- await this.draftManager.finalize(sessionId, thread, isAssistant);
1826
- const meta = content.metadata ?? {};
1827
- await this.toolTracker.trackNewCall(sessionId, thread, {
1828
- id: String(meta.id ?? ""),
1829
- name: content.text || String(meta.name ?? "Tool"),
1830
- kind: meta.kind,
1831
- status: String(meta.status ?? "running"),
1832
- content: meta.content,
1833
- viewerLinks: meta.viewerLinks,
1834
- viewerFilePath: meta.viewerFilePath
1835
- });
1836
- break;
1837
- }
1838
- case "tool_update": {
1839
- const meta = content.metadata ?? {};
1840
- await this.toolTracker.updateCall(sessionId, {
1841
- id: String(meta.id ?? ""),
1842
- name: content.text || String(meta.name ?? ""),
1843
- kind: meta.kind,
1844
- status: String(meta.status ?? "completed"),
1845
- content: meta.content,
1846
- viewerLinks: meta.viewerLinks,
1847
- viewerFilePath: meta.viewerFilePath
1855
+ return this.sessionTrackers.get(sessionId);
1856
+ }
1857
+ // --- MessageHandlers for dispatchMessage ---
1858
+ messageHandlers = {
1859
+ onThought: async (ctx, _content) => {
1860
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1861
+ await tracker.onThought();
1862
+ },
1863
+ onText: async (ctx, content) => {
1864
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1865
+ await tracker.onTextStart();
1866
+ const draft = this.draftManager.getOrCreate(ctx.sessionId, ctx.thread);
1867
+ draft.append(content.text);
1868
+ this.draftManager.appendText(ctx.sessionId, content.text);
1869
+ },
1870
+ onToolCall: async (ctx, content) => {
1871
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1872
+ await tracker.onToolCall();
1873
+ await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1874
+ const meta = content.metadata ?? {};
1875
+ await this.toolTracker.trackNewCall(ctx.sessionId, ctx.thread, {
1876
+ id: String(meta.id ?? ""),
1877
+ name: content.text || String(meta.name ?? "Tool"),
1878
+ kind: meta.kind,
1879
+ status: String(meta.status ?? "running"),
1880
+ content: meta.content,
1881
+ viewerLinks: meta.viewerLinks,
1882
+ viewerFilePath: meta.viewerFilePath
1883
+ });
1884
+ },
1885
+ onToolUpdate: async (ctx, content) => {
1886
+ const meta = content.metadata ?? {};
1887
+ await this.toolTracker.updateCall(ctx.sessionId, {
1888
+ id: String(meta.id ?? ""),
1889
+ name: content.text || String(meta.name ?? ""),
1890
+ kind: meta.kind,
1891
+ status: String(meta.status ?? "completed"),
1892
+ content: meta.content,
1893
+ viewerLinks: meta.viewerLinks,
1894
+ viewerFilePath: meta.viewerFilePath
1895
+ });
1896
+ },
1897
+ onPlan: async (ctx, content) => {
1898
+ const entries = content.metadata?.entries ?? [];
1899
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1900
+ await tracker.onPlan(entries);
1901
+ },
1902
+ onUsage: async (ctx, content) => {
1903
+ await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1904
+ const meta = content.metadata ?? {};
1905
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1906
+ await tracker.sendUsage({
1907
+ tokensUsed: meta.tokensUsed,
1908
+ contextSize: meta.contextSize
1909
+ });
1910
+ try {
1911
+ const deepLink = buildDeepLink(this.guild.id, ctx.thread.id);
1912
+ await this.sendNotification({
1913
+ sessionId: ctx.sessionId,
1914
+ type: "completed",
1915
+ summary: content.text || "Session completed",
1916
+ deepLink
1848
1917
  });
1849
- break;
1850
- }
1851
- case "plan": {
1852
- const entries = content.metadata?.entries ?? [];
1853
- await tracker.onPlan(entries);
1854
- break;
1918
+ } catch {
1855
1919
  }
1856
- case "usage": {
1857
- await this.draftManager.finalize(sessionId, thread, isAssistant);
1858
- const meta = content.metadata ?? {};
1859
- await tracker.sendUsage({
1860
- tokensUsed: meta.tokensUsed,
1861
- contextSize: meta.contextSize
1862
- });
1863
- try {
1864
- const deepLink = buildDeepLink(this.guild.id, thread.id);
1865
- await this.sendNotification({
1866
- sessionId,
1867
- type: "completed",
1868
- summary: content.text || "Session completed",
1869
- deepLink
1870
- });
1871
- } catch {
1872
- }
1873
- break;
1920
+ },
1921
+ onSessionEnd: async (ctx, _content) => {
1922
+ await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1923
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1924
+ await tracker.cleanup();
1925
+ this.toolTracker.cleanup(ctx.sessionId);
1926
+ this.sessionTrackers.delete(ctx.sessionId);
1927
+ await this.skillManager.cleanup(ctx.sessionId);
1928
+ try {
1929
+ await this.sendQueue.enqueue(
1930
+ () => ctx.thread.send({ content: "\u2705 Done" }),
1931
+ { type: "other" }
1932
+ );
1933
+ } catch {
1874
1934
  }
1875
- case "session_end": {
1876
- await this.draftManager.finalize(sessionId, thread, isAssistant);
1877
- await tracker.cleanup();
1878
- this.toolTracker.cleanup(sessionId);
1879
- this.sessionTrackers.delete(sessionId);
1880
- await this.skillManager.cleanup(sessionId);
1881
- try {
1882
- await this.sendQueue.enqueue(
1883
- () => thread.send({ content: "\u2705 Done" }),
1884
- { type: "other" }
1885
- );
1886
- } catch {
1887
- }
1888
- break;
1935
+ },
1936
+ onError: async (ctx, content) => {
1937
+ await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1938
+ const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1939
+ await tracker.cleanup();
1940
+ this.toolTracker.cleanup(ctx.sessionId);
1941
+ this.sessionTrackers.delete(ctx.sessionId);
1942
+ try {
1943
+ await this.sendQueue.enqueue(
1944
+ () => ctx.thread.send({ content: `\u274C Error: ${content.text}` }),
1945
+ { type: "other" }
1946
+ );
1947
+ } catch {
1889
1948
  }
1890
- case "error": {
1891
- await this.draftManager.finalize(sessionId, thread, isAssistant);
1892
- await tracker.cleanup();
1893
- this.toolTracker.cleanup(sessionId);
1894
- this.sessionTrackers.delete(sessionId);
1949
+ },
1950
+ onAttachment: async (ctx, content) => {
1951
+ if (!content.attachment) return;
1952
+ const { attachment } = content;
1953
+ await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1954
+ if (isAttachmentTooLarge(attachment.size)) {
1955
+ log.warn({ sessionId: ctx.sessionId, fileName: attachment.fileName, size: attachment.size }, "[discord-media] File too large (>25MB)");
1895
1956
  try {
1896
1957
  await this.sendQueue.enqueue(
1897
- () => thread.send({ content: `\u274C Error: ${content.text}` }),
1958
+ () => ctx.thread.send({ content: `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${attachment.fileName}` }),
1898
1959
  { type: "other" }
1899
1960
  );
1900
1961
  } catch {
1901
1962
  }
1902
- break;
1963
+ return;
1903
1964
  }
1904
- case "attachment": {
1905
- if (!content.attachment) break;
1906
- const { attachment } = content;
1907
- await this.draftManager.finalize(sessionId, thread, isAssistant);
1908
- if (isAttachmentTooLarge(attachment.size)) {
1909
- log.warn({ sessionId, fileName: attachment.fileName, size: attachment.size }, "[discord-media] File too large (>25MB)");
1910
- try {
1911
- await this.sendQueue.enqueue(
1912
- () => thread.send({ content: `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${attachment.fileName}` }),
1913
- { type: "other" }
1914
- );
1915
- } catch {
1965
+ try {
1966
+ await this.sendQueue.enqueue(
1967
+ () => ctx.thread.send({ files: [{ attachment: attachment.filePath, name: attachment.fileName }] }),
1968
+ { type: "other" }
1969
+ );
1970
+ if (attachment.type === "audio") {
1971
+ const draft = this.draftManager.getDraft(ctx.sessionId);
1972
+ if (draft) {
1973
+ draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
1974
+ });
1916
1975
  }
1917
- break;
1918
1976
  }
1919
- try {
1920
- await this.sendQueue.enqueue(
1921
- () => thread.send({ files: [{ attachment: attachment.filePath, name: attachment.fileName }] }),
1922
- { type: "other" }
1923
- );
1924
- } catch (err) {
1925
- log.error({ err, sessionId, fileName: attachment.fileName }, "[discord-media] Failed to send attachment");
1926
- }
1927
- break;
1977
+ } catch (err) {
1978
+ log.error({ err, sessionId: ctx.sessionId, fileName: attachment.fileName }, "[discord-media] Failed to send attachment");
1928
1979
  }
1929
- case "system_message": {
1930
- try {
1931
- await this.sendQueue.enqueue(
1932
- () => thread.send({ content: content.text }),
1933
- { type: "other" }
1934
- );
1935
- } catch {
1936
- }
1937
- break;
1980
+ },
1981
+ onSystemMessage: async (ctx, content) => {
1982
+ try {
1983
+ await this.sendQueue.enqueue(
1984
+ () => ctx.thread.send({ content: content.text }),
1985
+ { type: "other" }
1986
+ );
1987
+ } catch {
1938
1988
  }
1939
1989
  }
1990
+ };
1991
+ // ─── sendMessage ──────────────────────────────────────────────────────────
1992
+ async sendMessage(sessionId, content) {
1993
+ if (this.assistantInitializing && this.assistantSession && sessionId === this.assistantSession.id) {
1994
+ return;
1995
+ }
1996
+ const thread = await this.getThread(sessionId);
1997
+ if (!thread) return;
1998
+ await ensureUnarchived(thread);
1999
+ const isAssistant = this.assistantSession != null && sessionId === this.assistantSession.id;
2000
+ const ctx = { sessionId, thread, isAssistant };
2001
+ await dispatchMessage(this.messageHandlers, ctx, content);
1940
2002
  }
1941
2003
  // ─── sendPermissionRequest ────────────────────────────────────────────────
1942
2004
  async sendPermissionRequest(sessionId, request) {
@@ -1945,14 +2007,6 @@ var DiscordAdapter = class extends ChannelAdapter {
1945
2007
  log.warn({ sessionId }, "[DiscordAdapter] sendPermissionRequest: session not found");
1946
2008
  return;
1947
2009
  }
1948
- const autoApprove = request.description.toLowerCase().includes("openacp") || session.dangerousMode;
1949
- if (autoApprove) {
1950
- const allowOption = request.options.find((o) => o.isAllow);
1951
- if (allowOption && session.permissionGate.requestId === request.id) {
1952
- session.permissionGate.resolve(allowOption.id);
1953
- }
1954
- return;
1955
- }
1956
2010
  const thread = await this.getThread(sessionId);
1957
2011
  if (!thread) return;
1958
2012
  await this.permissionHandler.sendPermissionRequest(session, request, thread);
@@ -2041,4 +2095,4 @@ ${notification.deepLink}`;
2041
2095
  export {
2042
2096
  DiscordAdapter
2043
2097
  };
2044
- //# sourceMappingURL=discord-2DKRH45T.js.map
2098
+ //# sourceMappingURL=discord-VHCBN3JJ.js.map