@ashx-j/lunr 0.2.19 → 0.2.20
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/CHANGELOG.md +23 -0
- package/README.md +2 -2
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +0 -2
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts +6 -4
- package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js +93 -49
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +351 -351
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +80 -43
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +36 -11
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +21 -12
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +7 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +225 -15
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts +29 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +9 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +34 -9
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +1 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +54 -38
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -6
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +62 -16
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +13 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +5 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +3 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +16 -4
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +24 -6
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +44 -4
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +227 -133
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js.map +1 -1
- package/dist/core/permissions.d.ts +1 -0
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +8 -4
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +0 -5
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/runtime-bridges.d.ts.map +1 -1
- package/dist/core/runtime-bridges.js +0 -2
- package/dist/core/runtime-bridges.js.map +1 -1
- package/dist/core/subagent-cancellation.d.ts +21 -0
- package/dist/core/subagent-cancellation.d.ts.map +1 -0
- package/dist/core/subagent-cancellation.js +53 -0
- package/dist/core/subagent-cancellation.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +12 -18
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +12 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +29 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/node-runtime/{agent-session-services-35WNVGMR.js → agent-session-services-75JKASCW.js} +3 -3
- package/dist/node-runtime/{builtin-extensions-322XDDEM.js → builtin-extensions-X4JMM4ZS.js} +2 -2
- package/dist/node-runtime/{chunk-XATUM2HK.js → chunk-25I2BHAA.js} +1 -1
- package/dist/node-runtime/{chunk-MCUNIRD5.js → chunk-46ECNOLF.js} +477 -246
- package/dist/node-runtime/{chunk-J26TSGDL.js → chunk-6N22HULO.js} +8 -5
- package/dist/node-runtime/{chunk-TFBIJTM3.js → chunk-AL2FMKKM.js} +7 -7
- package/dist/node-runtime/chunk-AOFXZQKA.js +24 -0
- package/dist/node-runtime/chunk-BBUVIEZB.js +51 -0
- package/dist/node-runtime/{chunk-ZRCBN365.js → chunk-ELWEXVO5.js} +7 -7
- package/dist/node-runtime/{chunk-ATGA2WLC.js → chunk-JYNNB7DU.js} +397 -34
- package/dist/node-runtime/{chunk-4FX25LWP.js → chunk-K3646JTM.js} +16 -117
- package/dist/node-runtime/{chunk-PNJSG3IZ.js → chunk-LTYWTR3V.js} +1 -369
- package/dist/node-runtime/{chunk-TXHKBRHZ.js → chunk-QKFMBRAL.js} +45 -31
- package/dist/node-runtime/{command-DWUM5X3U.js → command-RBTRL55A.js} +1 -1
- package/dist/node-runtime/{gateway-UZXMFGWY.js → gateway-L4ANRTVE.js} +2 -2
- package/dist/node-runtime/index.js +9 -8
- package/dist/node-runtime/{interactive-mode-QT5IKGQ5.js → interactive-mode-HPUNH7SV.js} +5 -4
- package/dist/node-runtime/{lunr-cron-QPBTKBGI.js → lunr-cron-NNYTWTGF.js} +2 -2
- package/dist/node-runtime/main.js +7 -7
- package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-DDQMRNPJ.js} +96 -76
- package/dist/node-runtime/{pi-subagents-7YJ3I4VE.js → pi-subagents-T5WMMLBB.js} +1040 -318
- package/dist/node-runtime/rpc-entry.js +7 -7
- package/dist/node-runtime/{runtime-bridges-3RKBDLNA.js → runtime-bridges-NJQERQ72.js} +2 -4
- package/dist/node-runtime/{subagent-executor-5Q5A4HJ2.js → subagent-executor-SRFC26SJ.js} +168 -249
- package/docs/features.md +17 -3
- package/docs/keybindings.md +3 -1
- package/docs/settings.md +1 -1
- package/package.json +4 -4
- package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
- package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
- package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
- package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
- package/dist/core/settings-tools-bridge.d.ts +0 -35
- package/dist/core/settings-tools-bridge.d.ts.map +0 -1
- package/dist/core/settings-tools-bridge.js +0 -56
- package/dist/core/settings-tools-bridge.js.map +0 -1
- package/dist/node-runtime/chunk-3NMWLTPV.js +0 -64
|
@@ -3,7 +3,7 @@ import { randomUUID } from "crypto";
|
|
|
3
3
|
import { Type } from "typebox";
|
|
4
4
|
import { Text } from "@ashx-j/lunr-tui";
|
|
5
5
|
import { IntercomClient } from "./broker/client.js";
|
|
6
|
-
import { spawnBrokerIfNeeded } from "./broker/spawn.js";
|
|
6
|
+
import { isNativeSupervisorChannelActive, spawnBrokerIfNeeded } from "./broker/spawn.js";
|
|
7
7
|
import { SessionListOverlay } from "./ui/session-list.js";
|
|
8
8
|
import { ComposeOverlay } from "./ui/compose.js";
|
|
9
9
|
import { InlineMessageComponent } from "./ui/inline-message.js";
|
|
@@ -875,6 +875,9 @@ export default function piIntercomExtension(pi) {
|
|
|
875
875
|
agentRunning = false;
|
|
876
876
|
activeTools.clear();
|
|
877
877
|
startNamePoll();
|
|
878
|
+
if (isNativeSupervisorChannelActive()) {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
878
881
|
const startupGeneration = runtimeGeneration;
|
|
879
882
|
startupConnectTimer = setTimeout(() => {
|
|
880
883
|
startupConnectTimer = null;
|
|
@@ -899,67 +902,62 @@ export default function piIntercomExtension(pi) {
|
|
|
899
902
|
...(error ? { error: getErrorMessage(error) } : {}),
|
|
900
903
|
});
|
|
901
904
|
}
|
|
905
|
+
const resultDeliveries = new Map();
|
|
906
|
+
const acknowledgedResults = [];
|
|
902
907
|
function relaySubagentIntercomPayload(payload, options) {
|
|
903
908
|
const parsed = parseSubagentIntercomPayload(payload);
|
|
904
909
|
if (!parsed)
|
|
905
910
|
return;
|
|
906
911
|
const relayGeneration = runtimeGeneration;
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
}
|
|
932
|
-
if (!relayStillLive()) {
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
if (currentSessionTargetMatches(parsed.to, target, activeClient)) {
|
|
936
|
-
deliverLocalSubagentRelayMessage(options.sender, options.status, parsed.message);
|
|
937
|
-
if (options.acknowledge)
|
|
938
|
-
emitResultDelivery(parsed.requestId, true);
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
try {
|
|
942
|
-
const result = await activeClient.send(target, { text: parsed.message });
|
|
943
|
-
if (!relayStillLive())
|
|
944
|
-
return;
|
|
945
|
-
if (!result.delivered) {
|
|
946
|
-
const error = new Error(result.reason ?? "Session may not exist or has disconnected.");
|
|
947
|
-
recordSubagentDeliveryError(options.errorEntryType, parsed.to, parsed.message, error);
|
|
948
|
-
if (options.acknowledge)
|
|
949
|
-
emitResultDelivery(parsed.requestId, false, error);
|
|
950
|
-
return;
|
|
912
|
+
const key = options.acknowledge && parsed.requestId ? `${relayGeneration}:${parsed.requestId}` : undefined;
|
|
913
|
+
let delivery = key ? resultDeliveries.get(key) : undefined;
|
|
914
|
+
if (!delivery) {
|
|
915
|
+
delivery = (async () => {
|
|
916
|
+
const relayStillLive = () => !runtimeStarted || Boolean(getLiveContext(runtimeContext, relayGeneration));
|
|
917
|
+
try {
|
|
918
|
+
if (!relayStillLive())
|
|
919
|
+
return false;
|
|
920
|
+
if (currentSessionTargetMatches(parsed.to)) {
|
|
921
|
+
deliverLocalSubagentRelayMessage(options.sender, options.status, parsed.message);
|
|
922
|
+
return true;
|
|
923
|
+
}
|
|
924
|
+
const activeClient = await ensureConnected("background");
|
|
925
|
+
const target = await resolveSessionTarget(activeClient, parsed.to) ?? parsed.to;
|
|
926
|
+
if (!relayStillLive())
|
|
927
|
+
return false;
|
|
928
|
+
if (currentSessionTargetMatches(parsed.to, target, activeClient)) {
|
|
929
|
+
deliverLocalSubagentRelayMessage(options.sender, options.status, parsed.message);
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
932
|
+
const result = await activeClient.send(target, { text: parsed.message });
|
|
933
|
+
if (!result.delivered)
|
|
934
|
+
throw new Error(result.reason ?? "Session may not exist or has disconnected.");
|
|
935
|
+
return true;
|
|
951
936
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
937
|
+
catch (error) {
|
|
938
|
+
if (relayStillLive())
|
|
939
|
+
recordSubagentDeliveryError(options.errorEntryType, parsed.to, parsed.message, error);
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
})();
|
|
943
|
+
if (key) {
|
|
944
|
+
resultDeliveries.set(key, delivery);
|
|
945
|
+
void delivery.then((delivered) => {
|
|
946
|
+
if (!delivered) {
|
|
947
|
+
if (resultDeliveries.get(key) === delivery)
|
|
948
|
+
resultDeliveries.delete(key);
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
acknowledgedResults.push(key);
|
|
952
|
+
while (acknowledgedResults.length > 1024)
|
|
953
|
+
resultDeliveries.delete(acknowledgedResults.shift());
|
|
954
|
+
});
|
|
961
955
|
}
|
|
962
|
-
}
|
|
956
|
+
}
|
|
957
|
+
void delivery.then((delivered) => {
|
|
958
|
+
if (options.acknowledge)
|
|
959
|
+
emitResultDelivery(parsed.requestId, delivered);
|
|
960
|
+
});
|
|
963
961
|
}
|
|
964
962
|
const unsubscribeSubagentControlIntercom = pi.events.on(SUBAGENT_CONTROL_INTERCOM_EVENT, (payload) => {
|
|
965
963
|
relaySubagentIntercomPayload(payload, {
|
|
@@ -1100,7 +1098,8 @@ export default function piIntercomExtension(pi) {
|
|
|
1100
1098
|
}
|
|
1101
1099
|
});
|
|
1102
1100
|
const childOrchestratorMetadata = readChildOrchestratorMetadata();
|
|
1103
|
-
|
|
1101
|
+
const nativeSupervisorChannel = isNativeSupervisorChannelActive();
|
|
1102
|
+
if (childOrchestratorMetadata && !nativeSupervisorChannel) {
|
|
1104
1103
|
pi.registerTool({
|
|
1105
1104
|
name: "contact_supervisor",
|
|
1106
1105
|
label: "Contact Supervisor",
|
|
@@ -1361,10 +1360,11 @@ export default function piIntercomExtension(pi) {
|
|
|
1361
1360
|
},
|
|
1362
1361
|
});
|
|
1363
1362
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1363
|
+
if (!nativeSupervisorChannel)
|
|
1364
|
+
pi.registerTool({
|
|
1365
|
+
name: "intercom",
|
|
1366
|
+
label: "Intercom",
|
|
1367
|
+
description: `Send a message to another pi session running on this machine.
|
|
1368
1368
|
Use this to communicate findings, request help, or coordinate work with other sessions.
|
|
1369
1369
|
|
|
1370
1370
|
Usage:
|
|
@@ -1374,158 +1374,131 @@ Usage:
|
|
|
1374
1374
|
intercom({ action: "reply", message: "..." }) → Reply to the active/single pending ask
|
|
1375
1375
|
intercom({ action: "pending" }) → List unresolved inbound asks
|
|
1376
1376
|
intercom({ action: "status" }) → Show connection status`,
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1377
|
+
promptSnippet: "Use to coordinate with other local pi sessions: list peers, send updates, ask for help, or check intercom connectivity.",
|
|
1378
|
+
parameters: Type.Object({
|
|
1379
|
+
action: StringEnum(["list", "send", "ask", "reply", "pending", "status"], {
|
|
1380
|
+
description: "Action: 'list', 'send', 'ask', 'reply', 'pending', or 'status'",
|
|
1381
|
+
}),
|
|
1382
|
+
to: Type.Optional(Type.String({
|
|
1383
|
+
description: "Target session name or ID (for 'send', 'ask', or disambiguating 'reply')",
|
|
1384
|
+
})),
|
|
1385
|
+
message: Type.Optional(Type.String({
|
|
1386
|
+
description: "Message to send (for 'send', 'ask', or 'reply' action)",
|
|
1387
|
+
})),
|
|
1388
|
+
attachments: Type.Optional(Type.Array(Type.Object({
|
|
1389
|
+
type: StringEnum(["file", "snippet", "context"]),
|
|
1390
|
+
name: Type.String(),
|
|
1391
|
+
content: Type.String(),
|
|
1392
|
+
language: Type.Optional(Type.String()),
|
|
1393
|
+
}))),
|
|
1394
|
+
replyTo: Type.Optional(Type.String({
|
|
1395
|
+
description: "Message ID to reply to (for threading or responding to an 'ask')",
|
|
1396
|
+
})),
|
|
1381
1397
|
}),
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
if (!currentSession) {
|
|
1398
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
1399
|
+
let connectedClient;
|
|
1400
|
+
try {
|
|
1401
|
+
connectedClient = await ensureConnected("tool");
|
|
1402
|
+
}
|
|
1403
|
+
catch (error) {
|
|
1404
|
+
return {
|
|
1405
|
+
content: [{ type: "text", text: `Intercom not connected: ${getErrorMessage(error)}` }],
|
|
1406
|
+
details: { error: true },
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
syncPresenceIdentity(ctx.sessionManager.getSessionId());
|
|
1410
|
+
const { action, to, message, attachments, replyTo } = params;
|
|
1411
|
+
switch (action) {
|
|
1412
|
+
case "list": {
|
|
1413
|
+
try {
|
|
1414
|
+
const mySessionId = connectedClient.sessionId;
|
|
1415
|
+
const sessions = await connectedClient.listSessions();
|
|
1416
|
+
const currentSession = sessions.find(s => s.id === mySessionId);
|
|
1417
|
+
const otherSessions = sessions.filter(s => s.id !== mySessionId);
|
|
1418
|
+
if (!currentSession) {
|
|
1419
|
+
return {
|
|
1420
|
+
content: [{ type: "text", text: "Current session is missing from intercom session list." }],
|
|
1421
|
+
details: { error: true },
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
const currentSection = `**Current session:**\n${formatSessionListRow(currentSession, currentSession.cwd, true)}`;
|
|
1425
|
+
const otherSection = otherSessions.length === 0
|
|
1426
|
+
? "**Other sessions:**\nNo other sessions connected."
|
|
1427
|
+
: `**Other sessions:**\n${otherSessions.map(s => formatSessionListRow(s, currentSession.cwd, false)).join("\n")}`;
|
|
1428
|
+
return {
|
|
1429
|
+
content: [{ type: "text", text: `${currentSection}\n\n${otherSection}` }],
|
|
1430
|
+
details: {},
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
catch (error) {
|
|
1419
1434
|
return {
|
|
1420
|
-
content: [{ type: "text", text:
|
|
1435
|
+
content: [{ type: "text", text: `Failed to list sessions: ${getErrorMessage(error)}` }],
|
|
1421
1436
|
details: { error: true },
|
|
1422
1437
|
};
|
|
1423
1438
|
}
|
|
1424
|
-
const currentSection = `**Current session:**\n${formatSessionListRow(currentSession, currentSession.cwd, true)}`;
|
|
1425
|
-
const otherSection = otherSessions.length === 0
|
|
1426
|
-
? "**Other sessions:**\nNo other sessions connected."
|
|
1427
|
-
: `**Other sessions:**\n${otherSessions.map(s => formatSessionListRow(s, currentSession.cwd, false)).join("\n")}`;
|
|
1428
|
-
return {
|
|
1429
|
-
content: [{ type: "text", text: `${currentSection}\n\n${otherSection}` }],
|
|
1430
|
-
details: {},
|
|
1431
|
-
};
|
|
1432
|
-
}
|
|
1433
|
-
catch (error) {
|
|
1434
|
-
return {
|
|
1435
|
-
content: [{ type: "text", text: `Failed to list sessions: ${getErrorMessage(error)}` }],
|
|
1436
|
-
details: { error: true },
|
|
1437
|
-
};
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
case "send": {
|
|
1441
|
-
if (!to || !message) {
|
|
1442
|
-
return {
|
|
1443
|
-
content: [{ type: "text", text: "Missing 'to' or 'message' parameter" }],
|
|
1444
|
-
details: { error: true },
|
|
1445
|
-
};
|
|
1446
1439
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
if (sendTo === connectedClient.sessionId) {
|
|
1440
|
+
case "send": {
|
|
1441
|
+
if (!to || !message) {
|
|
1450
1442
|
return {
|
|
1451
|
-
content: [{ type: "text", text: "
|
|
1443
|
+
content: [{ type: "text", text: "Missing 'to' or 'message' parameter" }],
|
|
1452
1444
|
details: { error: true },
|
|
1453
1445
|
};
|
|
1454
1446
|
}
|
|
1455
|
-
|
|
1456
|
-
const
|
|
1457
|
-
|
|
1458
|
-
if (!confirmed) {
|
|
1447
|
+
try {
|
|
1448
|
+
const sendTo = await resolveSessionTarget(connectedClient, to) ?? to;
|
|
1449
|
+
if (sendTo === connectedClient.sessionId) {
|
|
1459
1450
|
return {
|
|
1460
|
-
content: [{ type: "text", text: "
|
|
1461
|
-
details: {},
|
|
1451
|
+
content: [{ type: "text", text: "Cannot message the current session" }],
|
|
1452
|
+
details: { error: true },
|
|
1462
1453
|
};
|
|
1463
1454
|
}
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1455
|
+
if (!replyTo && config.confirmSend && ctx.hasUI) {
|
|
1456
|
+
const attachmentText = attachments?.length ? formatAttachments(attachments) : "";
|
|
1457
|
+
const confirmed = await ctx.ui.confirm("Send Message", `Send to "${to}":\n\n${message}${attachmentText}`);
|
|
1458
|
+
if (!confirmed) {
|
|
1459
|
+
return {
|
|
1460
|
+
content: [{ type: "text", text: "Message cancelled by user" }],
|
|
1461
|
+
details: {},
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
const result = await connectedClient.send(sendTo, {
|
|
1466
|
+
text: message,
|
|
1467
|
+
attachments,
|
|
1468
|
+
replyTo,
|
|
1469
|
+
});
|
|
1470
|
+
if (!result.delivered) {
|
|
1471
|
+
const errorText = result.reason ?? "Session may not exist or has disconnected.";
|
|
1472
|
+
return {
|
|
1473
|
+
content: [{ type: "text", text: `Message to "${to}" was not delivered: ${errorText}` }],
|
|
1474
|
+
details: { messageId: result.id, delivered: false, reason: result.reason },
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
pi.appendEntry("intercom_sent", {
|
|
1478
|
+
to,
|
|
1479
|
+
message: { text: message, attachments, replyTo },
|
|
1480
|
+
messageId: result.id,
|
|
1481
|
+
timestamp: Date.now(),
|
|
1482
|
+
});
|
|
1483
|
+
if (replyTo) {
|
|
1484
|
+
replyTracker.markReplied(replyTo);
|
|
1485
|
+
}
|
|
1472
1486
|
return {
|
|
1473
|
-
content: [{ type: "text", text: `Message to
|
|
1474
|
-
details: { messageId: result.id, delivered:
|
|
1487
|
+
content: [{ type: "text", text: `Message sent to ${to}` }],
|
|
1488
|
+
details: { messageId: result.id, delivered: true },
|
|
1475
1489
|
};
|
|
1476
1490
|
}
|
|
1477
|
-
|
|
1478
|
-
to,
|
|
1479
|
-
message: { text: message, attachments, replyTo },
|
|
1480
|
-
messageId: result.id,
|
|
1481
|
-
timestamp: Date.now(),
|
|
1482
|
-
});
|
|
1483
|
-
if (replyTo) {
|
|
1484
|
-
replyTracker.markReplied(replyTo);
|
|
1485
|
-
}
|
|
1486
|
-
return {
|
|
1487
|
-
content: [{ type: "text", text: `Message sent to ${to}` }],
|
|
1488
|
-
details: { messageId: result.id, delivered: true },
|
|
1489
|
-
};
|
|
1490
|
-
}
|
|
1491
|
-
catch (error) {
|
|
1492
|
-
return {
|
|
1493
|
-
content: [{ type: "text", text: `Failed to send: ${getErrorMessage(error)}` }],
|
|
1494
|
-
details: { error: true },
|
|
1495
|
-
};
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
case "ask": {
|
|
1499
|
-
if (!to || !message) {
|
|
1500
|
-
return {
|
|
1501
|
-
content: [{ type: "text", text: "Missing 'to' or 'message' parameter" }],
|
|
1502
|
-
details: { error: true },
|
|
1503
|
-
};
|
|
1504
|
-
}
|
|
1505
|
-
if (replyWaiter) {
|
|
1506
|
-
return {
|
|
1507
|
-
content: [{ type: "text", text: "Already waiting for a reply" }],
|
|
1508
|
-
details: { error: true },
|
|
1509
|
-
};
|
|
1510
|
-
}
|
|
1511
|
-
if (_signal?.aborted) {
|
|
1512
|
-
return {
|
|
1513
|
-
content: [{ type: "text", text: "Cancelled" }],
|
|
1514
|
-
details: { error: true },
|
|
1515
|
-
};
|
|
1516
|
-
}
|
|
1517
|
-
let replyPromise = null;
|
|
1518
|
-
try {
|
|
1519
|
-
const sendTo = await resolveSessionTarget(connectedClient, to) ?? to;
|
|
1520
|
-
if (_signal?.aborted) {
|
|
1491
|
+
catch (error) {
|
|
1521
1492
|
return {
|
|
1522
|
-
content: [{ type: "text", text:
|
|
1493
|
+
content: [{ type: "text", text: `Failed to send: ${getErrorMessage(error)}` }],
|
|
1523
1494
|
details: { error: true },
|
|
1524
1495
|
};
|
|
1525
1496
|
}
|
|
1526
|
-
|
|
1497
|
+
}
|
|
1498
|
+
case "ask": {
|
|
1499
|
+
if (!to || !message) {
|
|
1527
1500
|
return {
|
|
1528
|
-
content: [{ type: "text", text: "
|
|
1501
|
+
content: [{ type: "text", text: "Missing 'to' or 'message' parameter" }],
|
|
1529
1502
|
details: { error: true },
|
|
1530
1503
|
};
|
|
1531
1504
|
}
|
|
@@ -1535,198 +1508,225 @@ Usage:
|
|
|
1535
1508
|
details: { error: true },
|
|
1536
1509
|
};
|
|
1537
1510
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1511
|
+
if (_signal?.aborted) {
|
|
1512
|
+
return {
|
|
1513
|
+
content: [{ type: "text", text: "Cancelled" }],
|
|
1514
|
+
details: { error: true },
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
let replyPromise = null;
|
|
1518
|
+
try {
|
|
1519
|
+
const sendTo = await resolveSessionTarget(connectedClient, to) ?? to;
|
|
1520
|
+
if (_signal?.aborted) {
|
|
1521
|
+
return {
|
|
1522
|
+
content: [{ type: "text", text: "Cancelled" }],
|
|
1523
|
+
details: { error: true },
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
if (sendTo === connectedClient.sessionId) {
|
|
1527
|
+
return {
|
|
1528
|
+
content: [{ type: "text", text: "Cannot message the current session" }],
|
|
1529
|
+
details: { error: true },
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
if (replyWaiter) {
|
|
1533
|
+
return {
|
|
1534
|
+
content: [{ type: "text", text: "Already waiting for a reply" }],
|
|
1535
|
+
details: { error: true },
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
const questionId = randomUUID();
|
|
1539
|
+
replyPromise = waitForReply(sendTo, questionId, _signal, () => connectedClient.cancelAsk(questionId));
|
|
1540
|
+
replyPromise.catch(() => undefined);
|
|
1541
|
+
const sendResult = await connectedClient.send(sendTo, {
|
|
1542
|
+
messageId: questionId,
|
|
1543
|
+
text: message,
|
|
1544
|
+
attachments,
|
|
1545
|
+
replyTo,
|
|
1546
|
+
expectsReply: true,
|
|
1547
|
+
});
|
|
1548
|
+
if (!sendResult.delivered) {
|
|
1549
|
+
const errorText = sendResult.reason ?? "Session may not exist or has disconnected.";
|
|
1550
|
+
rejectReplyWaiter(new Error(`Message to "${to}" was not delivered: ${errorText}`));
|
|
1551
|
+
if (replyPromise) {
|
|
1552
|
+
try {
|
|
1553
|
+
await replyPromise;
|
|
1554
|
+
}
|
|
1555
|
+
catch {
|
|
1556
|
+
// The waiter was already rejected above. Keep the delivery failure as the only error here.
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
return {
|
|
1560
|
+
content: [{ type: "text", text: `Message to "${to}" was not delivered: ${errorText}` }],
|
|
1561
|
+
details: { error: true },
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
pi.appendEntry("intercom_sent", {
|
|
1565
|
+
to,
|
|
1566
|
+
message: { text: message, attachments, replyTo },
|
|
1567
|
+
messageId: sendResult.id,
|
|
1568
|
+
timestamp: Date.now(),
|
|
1569
|
+
});
|
|
1570
|
+
const replyMessage = await replyPromise;
|
|
1571
|
+
const replyText = replyMessage.content.text;
|
|
1572
|
+
const replyAttachments = replyMessage.content.attachments?.length
|
|
1573
|
+
? formatAttachments(replyMessage.content.attachments)
|
|
1574
|
+
: "";
|
|
1575
|
+
pi.appendEntry("intercom_received", {
|
|
1576
|
+
from: to,
|
|
1577
|
+
message: { text: replyText, attachments: replyMessage.content.attachments },
|
|
1578
|
+
messageId: replyMessage.id,
|
|
1579
|
+
timestamp: replyMessage.timestamp,
|
|
1580
|
+
});
|
|
1581
|
+
return {
|
|
1582
|
+
content: [{ type: "text", text: `**Reply from ${to}:**\n${replyText}${replyAttachments}` }],
|
|
1583
|
+
details: {},
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
catch (error) {
|
|
1587
|
+
rejectReplyWaiter(toError(error));
|
|
1551
1588
|
if (replyPromise) {
|
|
1552
1589
|
try {
|
|
1553
1590
|
await replyPromise;
|
|
1554
1591
|
}
|
|
1555
1592
|
catch {
|
|
1556
|
-
// The waiter
|
|
1593
|
+
// The waiter is cleanup-only on this path. The real failure is the one from the outer catch.
|
|
1557
1594
|
}
|
|
1558
1595
|
}
|
|
1559
1596
|
return {
|
|
1560
|
-
content: [{ type: "text", text: `
|
|
1597
|
+
content: [{ type: "text", text: `Failed: ${getErrorMessage(error)}` }],
|
|
1561
1598
|
details: { error: true },
|
|
1562
1599
|
};
|
|
1563
1600
|
}
|
|
1564
|
-
pi.appendEntry("intercom_sent", {
|
|
1565
|
-
to,
|
|
1566
|
-
message: { text: message, attachments, replyTo },
|
|
1567
|
-
messageId: sendResult.id,
|
|
1568
|
-
timestamp: Date.now(),
|
|
1569
|
-
});
|
|
1570
|
-
const replyMessage = await replyPromise;
|
|
1571
|
-
const replyText = replyMessage.content.text;
|
|
1572
|
-
const replyAttachments = replyMessage.content.attachments?.length
|
|
1573
|
-
? formatAttachments(replyMessage.content.attachments)
|
|
1574
|
-
: "";
|
|
1575
|
-
pi.appendEntry("intercom_received", {
|
|
1576
|
-
from: to,
|
|
1577
|
-
message: { text: replyText, attachments: replyMessage.content.attachments },
|
|
1578
|
-
messageId: replyMessage.id,
|
|
1579
|
-
timestamp: replyMessage.timestamp,
|
|
1580
|
-
});
|
|
1581
|
-
return {
|
|
1582
|
-
content: [{ type: "text", text: `**Reply from ${to}:**\n${replyText}${replyAttachments}` }],
|
|
1583
|
-
details: {},
|
|
1584
|
-
};
|
|
1585
1601
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1602
|
+
case "reply": {
|
|
1603
|
+
if (!message) {
|
|
1604
|
+
return {
|
|
1605
|
+
content: [{ type: "text", text: "Missing 'message' parameter" }],
|
|
1606
|
+
details: { error: true },
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
try {
|
|
1610
|
+
const target = replyTracker.resolveReplyTarget({ to, replyTo });
|
|
1611
|
+
if (target.from.id === connectedClient.sessionId) {
|
|
1612
|
+
return {
|
|
1613
|
+
content: [{ type: "text", text: "Cannot message the current session" }],
|
|
1614
|
+
details: { error: true },
|
|
1615
|
+
};
|
|
1591
1616
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1617
|
+
const result = await connectedClient.send(target.from.id, {
|
|
1618
|
+
text: message,
|
|
1619
|
+
replyTo: target.message.id,
|
|
1620
|
+
});
|
|
1621
|
+
if (!result.delivered) {
|
|
1622
|
+
const errorText = result.reason ?? "Session may not exist or has disconnected.";
|
|
1623
|
+
if (result.reason === "Session not found") {
|
|
1624
|
+
replyTracker.dismissPendingAsk(target.message.id);
|
|
1625
|
+
}
|
|
1626
|
+
return {
|
|
1627
|
+
content: [{ type: "text", text: `Reply to "${target.from.name || target.from.id}" was not delivered: ${errorText}` }],
|
|
1628
|
+
details: { messageId: result.id, delivered: false, reason: result.reason },
|
|
1629
|
+
};
|
|
1594
1630
|
}
|
|
1631
|
+
replyTracker.markReplied(target.message.id);
|
|
1632
|
+
pi.appendEntry("intercom_sent", {
|
|
1633
|
+
to: target.from.name || target.from.id,
|
|
1634
|
+
message: { text: message, replyTo: target.message.id },
|
|
1635
|
+
messageId: result.id,
|
|
1636
|
+
timestamp: Date.now(),
|
|
1637
|
+
});
|
|
1638
|
+
return {
|
|
1639
|
+
content: [{ type: "text", text: `Reply sent to ${target.from.name || target.from.id}` }],
|
|
1640
|
+
details: { messageId: result.id, delivered: true, replyTo: target.message.id },
|
|
1641
|
+
};
|
|
1595
1642
|
}
|
|
1596
|
-
|
|
1597
|
-
content: [{ type: "text", text: `Failed: ${getErrorMessage(error)}` }],
|
|
1598
|
-
details: { error: true },
|
|
1599
|
-
};
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
case "reply": {
|
|
1603
|
-
if (!message) {
|
|
1604
|
-
return {
|
|
1605
|
-
content: [{ type: "text", text: "Missing 'message' parameter" }],
|
|
1606
|
-
details: { error: true },
|
|
1607
|
-
};
|
|
1608
|
-
}
|
|
1609
|
-
try {
|
|
1610
|
-
const target = replyTracker.resolveReplyTarget({ to, replyTo });
|
|
1611
|
-
if (target.from.id === connectedClient.sessionId) {
|
|
1643
|
+
catch (error) {
|
|
1612
1644
|
return {
|
|
1613
|
-
content: [{ type: "text", text:
|
|
1645
|
+
content: [{ type: "text", text: `Failed to reply: ${getErrorMessage(error)}` }],
|
|
1614
1646
|
details: { error: true },
|
|
1615
1647
|
};
|
|
1616
1648
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
if (!result.delivered) {
|
|
1622
|
-
const errorText = result.reason ?? "Session may not exist or has disconnected.";
|
|
1623
|
-
if (result.reason === "Session not found") {
|
|
1624
|
-
replyTracker.dismissPendingAsk(target.message.id);
|
|
1625
|
-
}
|
|
1649
|
+
}
|
|
1650
|
+
case "pending": {
|
|
1651
|
+
const pendingAsks = replyTracker.listPending();
|
|
1652
|
+
if (pendingAsks.length === 0) {
|
|
1626
1653
|
return {
|
|
1627
|
-
content: [{ type: "text", text:
|
|
1628
|
-
details: {
|
|
1654
|
+
content: [{ type: "text", text: "No unresolved inbound asks." }],
|
|
1655
|
+
details: {},
|
|
1629
1656
|
};
|
|
1630
1657
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
timestamp: Date.now(),
|
|
1658
|
+
const now = Date.now();
|
|
1659
|
+
const lines = pendingAsks.map(({ from, message, receivedAt }) => {
|
|
1660
|
+
const preview = message.content.text.replace(/\s+/g, " ").slice(0, 80);
|
|
1661
|
+
const elapsedSeconds = Math.max(0, Math.floor((now - receivedAt) / 1000));
|
|
1662
|
+
return `- ${from.name || from.id} · ${message.id} · ${elapsedSeconds}s ago · ${preview}`;
|
|
1637
1663
|
});
|
|
1638
1664
|
return {
|
|
1639
|
-
content: [{ type: "text", text:
|
|
1640
|
-
details: { messageId: result.id, delivered: true, replyTo: target.message.id },
|
|
1641
|
-
};
|
|
1642
|
-
}
|
|
1643
|
-
catch (error) {
|
|
1644
|
-
return {
|
|
1645
|
-
content: [{ type: "text", text: `Failed to reply: ${getErrorMessage(error)}` }],
|
|
1646
|
-
details: { error: true },
|
|
1647
|
-
};
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
case "pending": {
|
|
1651
|
-
const pendingAsks = replyTracker.listPending();
|
|
1652
|
-
if (pendingAsks.length === 0) {
|
|
1653
|
-
return {
|
|
1654
|
-
content: [{ type: "text", text: "No unresolved inbound asks." }],
|
|
1665
|
+
content: [{ type: "text", text: `**Pending asks:**\n${lines.join("\n")}` }],
|
|
1655
1666
|
details: {},
|
|
1656
1667
|
};
|
|
1657
1668
|
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
text: `**Intercom Status:**\nConnected: Yes\nSession ID: ${mySessionId}\nActive sessions: ${sessions.length}`,
|
|
1677
|
-
}],
|
|
1678
|
-
details: {},
|
|
1679
|
-
};
|
|
1669
|
+
case "status": {
|
|
1670
|
+
try {
|
|
1671
|
+
const mySessionId = connectedClient.sessionId;
|
|
1672
|
+
const sessions = await connectedClient.listSessions();
|
|
1673
|
+
return {
|
|
1674
|
+
content: [{
|
|
1675
|
+
type: "text",
|
|
1676
|
+
text: `**Intercom Status:**\nConnected: Yes\nSession ID: ${mySessionId}\nActive sessions: ${sessions.length}`,
|
|
1677
|
+
}],
|
|
1678
|
+
details: {},
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
catch (error) {
|
|
1682
|
+
return {
|
|
1683
|
+
content: [{ type: "text", text: `Failed to get status: ${getErrorMessage(error)}` }],
|
|
1684
|
+
details: { error: true },
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1680
1687
|
}
|
|
1681
|
-
|
|
1688
|
+
default:
|
|
1682
1689
|
return {
|
|
1683
|
-
content: [{ type: "text", text: `
|
|
1690
|
+
content: [{ type: "text", text: `Unknown action: ${action}` }],
|
|
1684
1691
|
details: { error: true },
|
|
1685
1692
|
};
|
|
1686
|
-
}
|
|
1687
1693
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
if (details?.reason && context.expanded) {
|
|
1725
|
-
text += "\n" + theme.fg("dim", `Reason: ${details.reason}`);
|
|
1726
|
-
}
|
|
1727
|
-
return new Text(text, 0, 0);
|
|
1728
|
-
},
|
|
1729
|
-
});
|
|
1694
|
+
},
|
|
1695
|
+
renderCall(args, theme) {
|
|
1696
|
+
const action = typeof args.action === "string" ? args.action : "intercom";
|
|
1697
|
+
const target = typeof args.to === "string" && args.to.trim() ? args.to.trim() : undefined;
|
|
1698
|
+
const messagePreview = previewText(args.message, 96);
|
|
1699
|
+
const attachmentCount = Array.isArray(args.attachments) ? args.attachments.length : 0;
|
|
1700
|
+
let text = theme.fg("toolTitle", theme.bold("intercom "));
|
|
1701
|
+
text += theme.fg(action === "ask" ? "warning" : action === "reply" ? "success" : "accent", action);
|
|
1702
|
+
if (target) {
|
|
1703
|
+
text += " " + theme.fg("muted", "→") + " " + theme.fg("accent", target);
|
|
1704
|
+
}
|
|
1705
|
+
if (attachmentCount > 0) {
|
|
1706
|
+
text += " " + theme.fg("dim", `(${attachmentCount} attachment${attachmentCount === 1 ? "" : "s"})`);
|
|
1707
|
+
}
|
|
1708
|
+
if (messagePreview) {
|
|
1709
|
+
text += "\n " + theme.fg("dim", messagePreview);
|
|
1710
|
+
}
|
|
1711
|
+
return new Text(text, 0, 0);
|
|
1712
|
+
},
|
|
1713
|
+
renderResult(result, { isPartial }, theme, context) {
|
|
1714
|
+
if (isPartial) {
|
|
1715
|
+
return new Text(theme.fg("warning", "Intercom working..."), 0, 0);
|
|
1716
|
+
}
|
|
1717
|
+
const details = result.details;
|
|
1718
|
+
const failed = Boolean(context.isError || details?.error === true || details?.delivered === false);
|
|
1719
|
+
let text = failed ? theme.fg("error", "✗ ") : theme.fg("success", "✓ ");
|
|
1720
|
+
text += theme.fg(failed ? "error" : "text", firstTextContent(result));
|
|
1721
|
+
if (details?.messageId && !context.expanded) {
|
|
1722
|
+
text += theme.fg("dim", ` (${details.messageId.slice(0, 8)})`);
|
|
1723
|
+
}
|
|
1724
|
+
if (details?.reason && context.expanded) {
|
|
1725
|
+
text += "\n" + theme.fg("dim", `Reason: ${details.reason}`);
|
|
1726
|
+
}
|
|
1727
|
+
return new Text(text, 0, 0);
|
|
1728
|
+
},
|
|
1729
|
+
});
|
|
1730
1730
|
async function openIntercomOverlay(ctx) {
|
|
1731
1731
|
const overlayGeneration = runtimeGeneration;
|
|
1732
1732
|
const liveContext = getLiveContext(ctx, overlayGeneration);
|