@llblab/pi-telegram 0.20.0 → 0.20.2
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/AGENTS.md +4 -1
- package/BACKLOG.md +5 -17
- package/CHANGELOG.md +22 -0
- package/README.md +61 -58
- package/docs/README.md +2 -2
- package/docs/architecture.md +5 -3
- package/docs/command-templates.md +7 -7
- package/docs/inbound.md +11 -11
- package/docs/multi-instance-bus.md +7 -4
- package/docs/outbound.md +5 -5
- package/index.ts +138 -208
- package/lib/bindings.ts +39 -13
- package/lib/bus-follower.ts +138 -7
- package/lib/bus-leader.ts +185 -43
- package/lib/bus-transport.ts +28 -4
- package/lib/bus.ts +83 -23
- package/lib/paths.ts +11 -0
- package/lib/prompts.ts +19 -7
- package/lib/setup.ts +27 -10
- package/lib/status.ts +9 -2
- package/lib/threads.ts +64 -26
- package/lib/turns.ts +0 -2
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -57,29 +57,31 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
57
57
|
setThinkingLevel,
|
|
58
58
|
} = piRuntime;
|
|
59
59
|
const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
|
|
60
|
-
const telegramInstanceId = `${process.pid}:${Date.now()}`;
|
|
61
|
-
// Manual follower identity must survive a Pi process reload in the same
|
|
62
|
-
// terminal. The process id changes on reload, but the parent shell/terminal id
|
|
63
|
-
// is stable enough to keep the follower bound to its existing Telegram thread.
|
|
64
|
-
const telegramManualFollowerOwnerId = String(process.ppid || process.pid);
|
|
65
60
|
const getActiveTelegramThreadProfile = function (): string | undefined {
|
|
66
61
|
return configStore.getActiveProfileName();
|
|
67
62
|
};
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
const busProcessRuntime = Bus.createTelegramBusProcessRuntime({
|
|
64
|
+
getActiveProfileName: getActiveTelegramThreadProfile,
|
|
65
|
+
pid: process.pid,
|
|
66
|
+
parentPid: process.ppid,
|
|
67
|
+
createdAtMs: Date.now(),
|
|
68
|
+
});
|
|
69
|
+
const {
|
|
70
|
+
instanceId: telegramInstanceId,
|
|
71
|
+
manualFollowerOwnerId: telegramManualFollowerOwnerId,
|
|
72
|
+
getLeaderSocketPath: getTelegramBusSocketPath,
|
|
73
|
+
getFollowerSocketPath: getTelegramBusFollowerSocketPath,
|
|
74
|
+
} = busProcessRuntime;
|
|
75
|
+
const getTelegramManualFollowerProfileKey =
|
|
76
|
+
BusFollower.createTelegramManualFollowerProfileKeyResolver({
|
|
77
|
+
getActiveProfileName: getActiveTelegramThreadProfile,
|
|
78
|
+
manualFollowerOwnerId: telegramManualFollowerOwnerId,
|
|
73
79
|
});
|
|
74
|
-
};
|
|
75
80
|
const telegramBusAuthSecret = Bus.createTelegramBusAuthSecret();
|
|
76
81
|
let telegramActiveBusAuthSecret: string | undefined;
|
|
77
82
|
let telegramBusLifecycleOverridePhase:
|
|
78
83
|
| Status.TelegramBridgeBusLifecyclePhase
|
|
79
84
|
| undefined;
|
|
80
|
-
const telegramBusSocketPath = Bus.getTelegramBusSocketPath();
|
|
81
|
-
const telegramBusFollowerSocketPath =
|
|
82
|
-
Bus.getTelegramBusFollowerSocketPath(telegramInstanceId);
|
|
83
85
|
let telegramBusRequestSequence = 0;
|
|
84
86
|
const telegramBusFollowerRegistry = Bus.createTelegramBusFollowerRegistry();
|
|
85
87
|
const telegramBusFollowerRegistrationState =
|
|
@@ -300,12 +302,13 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
300
302
|
},
|
|
301
303
|
getLocalBus() {
|
|
302
304
|
return {
|
|
303
|
-
leaderSocketPath:
|
|
304
|
-
leaderTransport:
|
|
305
|
-
|
|
306
|
-
|
|
305
|
+
leaderSocketPath: getTelegramBusSocketPath(),
|
|
306
|
+
leaderTransport: BusTransport.getTelegramBusTransportKind(
|
|
307
|
+
getTelegramBusSocketPath(),
|
|
308
|
+
),
|
|
309
|
+
followerSocketPath: getTelegramBusFollowerSocketPath(),
|
|
307
310
|
followerTransport: BusTransport.getTelegramBusTransportKind(
|
|
308
|
-
|
|
311
|
+
getTelegramBusFollowerSocketPath(),
|
|
309
312
|
),
|
|
310
313
|
followerRegistered: telegramBusFollowerRegistrationState.isRegistered(),
|
|
311
314
|
followerTarget: telegramBusFollowerRegistrationState.getTarget(),
|
|
@@ -412,7 +415,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
412
415
|
},
|
|
413
416
|
getDefaultTarget: proactivePushTargetGetter,
|
|
414
417
|
callFollowerApi: BusFollower.createTelegramBusFollowerApiCaller({
|
|
415
|
-
socketPath:
|
|
418
|
+
socketPath: getTelegramBusSocketPath,
|
|
416
419
|
instanceId: telegramInstanceId,
|
|
417
420
|
createRequestId() {
|
|
418
421
|
telegramBusRequestSequence += 1;
|
|
@@ -641,7 +644,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
641
644
|
Routing.TelegramRoutedCallbackQuery,
|
|
642
645
|
Routing.TelegramRoutedMessage
|
|
643
646
|
>({
|
|
644
|
-
socketPath:
|
|
647
|
+
socketPath: getTelegramBusSocketPath,
|
|
645
648
|
createRequestId() {
|
|
646
649
|
telegramBusRequestSequence += 1;
|
|
647
650
|
return Bus.createTelegramBusRequestId({
|
|
@@ -656,7 +659,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
656
659
|
});
|
|
657
660
|
const followerTargetController =
|
|
658
661
|
Bus.createTelegramBusFollowerTargetController({
|
|
659
|
-
socketPath:
|
|
662
|
+
socketPath: getTelegramBusSocketPath,
|
|
660
663
|
createRequestId() {
|
|
661
664
|
telegramBusRequestSequence += 1;
|
|
662
665
|
return Bus.createTelegramBusRequestId({
|
|
@@ -804,68 +807,72 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
804
807
|
compact,
|
|
805
808
|
recordRuntimeEvent,
|
|
806
809
|
});
|
|
807
|
-
const
|
|
808
|
-
BusFollower.
|
|
810
|
+
const promoteTelegramBusFollowerToLeader: BusFollower.TelegramBusFollowerPromotionHandler<Pi.ExtensionContext> =
|
|
811
|
+
BusFollower.createTelegramBusFollowerPromotionHandler<Pi.ExtensionContext>({
|
|
812
|
+
topicTargetStore: threadStore,
|
|
813
|
+
instanceId: telegramInstanceId,
|
|
814
|
+
getActiveProfileName: getActiveTelegramThreadProfile,
|
|
815
|
+
async startLeader(ctx): Promise<void> {
|
|
816
|
+
await lockedPollingRuntime.start(ctx, { force: true });
|
|
817
|
+
},
|
|
818
|
+
recordRuntimeEvent,
|
|
819
|
+
});
|
|
820
|
+
const telegramBusFollowerAssembly: BusFollower.TelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext> =
|
|
821
|
+
BusFollower.createTelegramBusFollowerRuntimeAssembly<
|
|
809
822
|
Pi.ExtensionContext,
|
|
810
823
|
Updates.TelegramMessageReactionUpdated,
|
|
811
824
|
Routing.TelegramRoutedCallbackQuery,
|
|
812
825
|
Routing.TelegramRoutedMessage
|
|
813
826
|
>({
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
827
|
+
receiver: {
|
|
828
|
+
socketPath: getTelegramBusFollowerSocketPath,
|
|
829
|
+
instanceId: telegramInstanceId,
|
|
830
|
+
getContext() {
|
|
831
|
+
return telegramSessionContextStore.get();
|
|
832
|
+
},
|
|
833
|
+
getAuthSecret() {
|
|
834
|
+
return telegramActiveBusAuthSecret;
|
|
835
|
+
},
|
|
836
|
+
handleForwardedCallback(query, ctx) {
|
|
837
|
+
return inboundRouteRuntime.handleUpdate({ callback_query: query }, ctx);
|
|
838
|
+
},
|
|
839
|
+
handleForwardedReaction(reactionUpdate, ctx) {
|
|
840
|
+
return inboundRouteRuntime.handleAuthorizedReactionUpdate(
|
|
841
|
+
reactionUpdate,
|
|
842
|
+
ctx,
|
|
843
|
+
);
|
|
844
|
+
},
|
|
845
|
+
handleForwardedMessage(message, ctx) {
|
|
846
|
+
return inboundRouteRuntime.handleUpdate(
|
|
847
|
+
{ message: message as never },
|
|
848
|
+
ctx,
|
|
849
|
+
);
|
|
850
|
+
},
|
|
851
|
+
async handleForwardedEditedMessage(message, ctx) {
|
|
852
|
+
return inboundRouteRuntime.handleUpdate(
|
|
853
|
+
{ edited_message: message as never },
|
|
854
|
+
ctx,
|
|
855
|
+
);
|
|
856
|
+
},
|
|
857
|
+
recordRuntimeEvent,
|
|
842
858
|
},
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
topicTargetStore: threadStore,
|
|
846
|
-
registrationState: telegramBusFollowerRegistrationState,
|
|
847
|
-
instanceId: telegramInstanceId,
|
|
848
|
-
manualFollowerProfileKey: getTelegramManualFollowerProfileKey(),
|
|
849
|
-
manualFollowerOwnerId: telegramManualFollowerOwnerId,
|
|
850
|
-
getSyncState() {
|
|
851
|
-
return telegramSyncState;
|
|
852
|
-
},
|
|
853
|
-
setSyncState(state) {
|
|
854
|
-
telegramSyncState = state;
|
|
855
|
-
},
|
|
856
|
-
updateStatus,
|
|
857
|
-
recordRuntimeEvent,
|
|
858
|
-
}),
|
|
859
|
-
recordRuntimeEvent,
|
|
860
|
-
});
|
|
861
|
-
let telegramBusFollowerRegistration: BusFollower.TelegramBusFollowerRegistrationRuntime<Pi.ExtensionContext>;
|
|
862
|
-
const telegramFollowerHeartbeatRecovery =
|
|
863
|
-
BusFollower.createTelegramBusFollowerHeartbeatRecoveryHandler<Pi.ExtensionContext>(
|
|
864
|
-
{
|
|
859
|
+
targetReplacement: {
|
|
860
|
+
topicTargetStore: threadStore,
|
|
865
861
|
registrationState: telegramBusFollowerRegistrationState,
|
|
866
|
-
|
|
867
|
-
|
|
862
|
+
instanceId: telegramInstanceId,
|
|
863
|
+
getManualFollowerProfileKey: getTelegramManualFollowerProfileKey,
|
|
864
|
+
manualFollowerOwnerId: telegramManualFollowerOwnerId,
|
|
865
|
+
getSyncState() {
|
|
866
|
+
return telegramSyncState;
|
|
867
|
+
},
|
|
868
|
+
setSyncState(state) {
|
|
869
|
+
telegramSyncState = state;
|
|
868
870
|
},
|
|
871
|
+
updateStatus,
|
|
872
|
+
recordRuntimeEvent,
|
|
873
|
+
},
|
|
874
|
+
recovery: {
|
|
875
|
+
registrationState: telegramBusFollowerRegistrationState,
|
|
869
876
|
getLeaderState() {
|
|
870
877
|
return lockRuntime.getState();
|
|
871
878
|
},
|
|
@@ -873,46 +880,17 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
873
880
|
telegramBusLifecycleOverridePhase = phase;
|
|
874
881
|
},
|
|
875
882
|
updateStatus,
|
|
876
|
-
|
|
877
|
-
const promotedRecord =
|
|
878
|
-
await Threads.promoteTelegramFollowerBindingToLeader({
|
|
879
|
-
store: threadStore,
|
|
880
|
-
instanceId: telegramInstanceId,
|
|
881
|
-
cwd: ctx.cwd,
|
|
882
|
-
telegramProfile: getActiveTelegramThreadProfile(),
|
|
883
|
-
target: binding.target,
|
|
884
|
-
slot: binding.slot,
|
|
885
|
-
threadName: binding.threadName,
|
|
886
|
-
});
|
|
887
|
-
if (promotedRecord) {
|
|
888
|
-
recordRuntimeEvent(
|
|
889
|
-
"bus",
|
|
890
|
-
"Follower thread binding promoted to leader",
|
|
891
|
-
{
|
|
892
|
-
phase: "follower-promoted-binding",
|
|
893
|
-
chatId: promotedRecord.target.chatId,
|
|
894
|
-
threadId: promotedRecord.target.threadId,
|
|
895
|
-
slot: promotedRecord.slot,
|
|
896
|
-
threadName: promotedRecord.threadName,
|
|
897
|
-
},
|
|
898
|
-
);
|
|
899
|
-
}
|
|
900
|
-
await lockedPollingRuntime.start(ctx, { force: true });
|
|
901
|
-
},
|
|
883
|
+
promoteToLeader: promoteTelegramBusFollowerToLeader,
|
|
902
884
|
sleep(ms) {
|
|
903
885
|
return Polling.sleepTelegramPollingRetry(ms);
|
|
904
886
|
},
|
|
905
887
|
promotionGraceMs: BusFollower.TELEGRAM_BUS_FOLLOWER_PROMOTION_GRACE_MS,
|
|
906
888
|
recordRuntimeEvent,
|
|
907
889
|
},
|
|
908
|
-
|
|
909
|
-
telegramBusFollowerRegistration =
|
|
910
|
-
BusFollower.createTelegramBusFollowerRegistrationRuntime<Pi.ExtensionContext>(
|
|
911
|
-
{
|
|
890
|
+
registration: {
|
|
912
891
|
instanceId: telegramInstanceId,
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
stopReceiving: telegramBusForwardedUpdateReceiver.stop,
|
|
892
|
+
getFollowerBusSocketPath: getTelegramBusFollowerSocketPath,
|
|
893
|
+
getLeaderSocketPath: getTelegramBusSocketPath,
|
|
916
894
|
registrationState: telegramBusFollowerRegistrationState,
|
|
917
895
|
createRequestId() {
|
|
918
896
|
telegramBusRequestSequence += 1;
|
|
@@ -933,10 +911,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
933
911
|
getProfileKey() {
|
|
934
912
|
return getTelegramManualFollowerProfileKey();
|
|
935
913
|
},
|
|
936
|
-
onHeartbeatFailure: telegramFollowerHeartbeatRecovery,
|
|
937
914
|
recordRuntimeEvent,
|
|
938
915
|
},
|
|
939
|
-
);
|
|
916
|
+
});
|
|
917
|
+
const telegramBusFollowerRegistration =
|
|
918
|
+
telegramBusFollowerAssembly.registration;
|
|
940
919
|
const pollingRuntime = Polling.createTelegramPollingControllerRuntime({
|
|
941
920
|
state: pollingControllerState,
|
|
942
921
|
getConfig: configStore.get,
|
|
@@ -966,116 +945,67 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
966
945
|
recordEvent: recordRuntimeEvent,
|
|
967
946
|
});
|
|
968
947
|
};
|
|
969
|
-
const telegramBusLeaderRuntime =
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
BusLeader.createTelegramBusLeaderTargetProvisioner<Pi.ExtensionContext>({
|
|
986
|
-
getAllowedUserId: configStore.getAllowedUserId,
|
|
987
|
-
instanceId: telegramInstanceId,
|
|
988
|
-
getCwd(ctx) {
|
|
989
|
-
return typeof ctx.cwd === "string" ? ctx.cwd : undefined;
|
|
990
|
-
},
|
|
991
|
-
getTelegramProfile: getActiveTelegramThreadProfile,
|
|
992
|
-
shouldForceFreshUnnamed() {
|
|
993
|
-
return forceFreshLeaderThreadOnNextStart;
|
|
994
|
-
},
|
|
995
|
-
topicTargetStore: threadStore,
|
|
996
|
-
callApi(method, body) {
|
|
997
|
-
return directTelegramApiRuntime.call(method, body);
|
|
998
|
-
},
|
|
999
|
-
getCurrentLeaderEpoch,
|
|
1000
|
-
getThreadReconciliationMachineState() {
|
|
1001
|
-
return threadReconciliationRuntime.getState();
|
|
1002
|
-
},
|
|
1003
|
-
recordThreadReconciliationPlan,
|
|
1004
|
-
getSyncState() {
|
|
1005
|
-
return telegramSyncState;
|
|
1006
|
-
},
|
|
1007
|
-
setSyncState(state) {
|
|
1008
|
-
telegramSyncState = state;
|
|
1009
|
-
},
|
|
1010
|
-
setLeaderTarget(input) {
|
|
1011
|
-
telegramBusLeaderTarget = input.target;
|
|
1012
|
-
telegramBusLeaderSlot = input.slot;
|
|
1013
|
-
telegramBusLeaderThreadName = input.threadName;
|
|
1014
|
-
},
|
|
1015
|
-
onProvisioningStart() {
|
|
1016
|
-
telegramTopicProvisioningCount += 1;
|
|
1017
|
-
},
|
|
1018
|
-
onProvisioningEnd() {
|
|
1019
|
-
telegramTopicProvisioningCount = Math.max(
|
|
1020
|
-
0,
|
|
1021
|
-
telegramTopicProvisioningCount - 1,
|
|
1022
|
-
);
|
|
948
|
+
const telegramBusLeaderRuntime =
|
|
949
|
+
BusLeader.createTelegramBusLeaderRuntimeAssembly<Pi.ExtensionContext>({
|
|
950
|
+
runtime: {
|
|
951
|
+
socketPath: getTelegramBusSocketPath,
|
|
952
|
+
followerRegistry: telegramBusFollowerRegistry,
|
|
953
|
+
authSecret: telegramBusAuthSecret,
|
|
954
|
+
startPolling: pollingRuntime.start,
|
|
955
|
+
stopPolling: pollingRuntime.stop,
|
|
956
|
+
authorizeFollowerApiCall: Bus.isTelegramFollowerApiCallAllowed,
|
|
957
|
+
recordFollowerMessageOwnership(record) {
|
|
958
|
+
messageOwnershipStore.record({
|
|
959
|
+
chatId: record.chatId,
|
|
960
|
+
messageId: record.messageId,
|
|
961
|
+
target: record.target,
|
|
962
|
+
instanceId: record.follower.instanceId,
|
|
963
|
+
});
|
|
1023
964
|
},
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
965
|
+
},
|
|
966
|
+
getAllowedUserId: configStore.getAllowedUserId,
|
|
967
|
+
instanceId: telegramInstanceId,
|
|
968
|
+
getCwd(ctx) {
|
|
969
|
+
return typeof ctx.cwd === "string" ? ctx.cwd : undefined;
|
|
970
|
+
},
|
|
971
|
+
getTelegramProfile: getActiveTelegramThreadProfile,
|
|
972
|
+
shouldForceFreshUnnamed() {
|
|
973
|
+
return forceFreshLeaderThreadOnNextStart;
|
|
974
|
+
},
|
|
1027
975
|
topicTargetStore: threadStore,
|
|
1028
976
|
callApi(method, body) {
|
|
1029
977
|
return directTelegramApiRuntime.call(method, body);
|
|
1030
978
|
},
|
|
979
|
+
callMultipart: directTelegramApiRuntime.callMultipart,
|
|
980
|
+
downloadFile: directTelegramApiRuntime.downloadFile,
|
|
981
|
+
recoverStaleTargetError: recoverStaleTelegramTopicApiError,
|
|
1031
982
|
getCurrentLeaderEpoch,
|
|
983
|
+
getThreadReconciliationMachineState() {
|
|
984
|
+
return threadReconciliationRuntime.getState();
|
|
985
|
+
},
|
|
986
|
+
recordThreadReconciliationPlan,
|
|
1032
987
|
getSyncState() {
|
|
1033
988
|
return telegramSyncState;
|
|
1034
989
|
},
|
|
1035
990
|
setSyncState(state) {
|
|
1036
991
|
telegramSyncState = state;
|
|
1037
992
|
},
|
|
993
|
+
setLeaderTarget(input) {
|
|
994
|
+
telegramBusLeaderTarget = input.target;
|
|
995
|
+
telegramBusLeaderSlot = input.slot;
|
|
996
|
+
telegramBusLeaderThreadName = input.threadName;
|
|
997
|
+
},
|
|
998
|
+
onProvisioningStart() {
|
|
999
|
+
telegramTopicProvisioningCount += 1;
|
|
1000
|
+
},
|
|
1001
|
+
onProvisioningEnd() {
|
|
1002
|
+
telegramTopicProvisioningCount = Math.max(
|
|
1003
|
+
0,
|
|
1004
|
+
telegramTopicProvisioningCount - 1,
|
|
1005
|
+
);
|
|
1006
|
+
},
|
|
1038
1007
|
recordRuntimeEvent,
|
|
1039
|
-
})
|
|
1040
|
-
provisionFollowerTarget:
|
|
1041
|
-
BusLeader.createTelegramBusFollowerTargetProvisioner({
|
|
1042
|
-
getAllowedUserId: configStore.getAllowedUserId,
|
|
1043
|
-
topicTargetStore: threadStore,
|
|
1044
|
-
callApi(method, body) {
|
|
1045
|
-
return directTelegramApiRuntime.call(method, body);
|
|
1046
|
-
},
|
|
1047
|
-
getCurrentLeaderEpoch,
|
|
1048
|
-
getSyncState() {
|
|
1049
|
-
return telegramSyncState;
|
|
1050
|
-
},
|
|
1051
|
-
setSyncState(state) {
|
|
1052
|
-
telegramSyncState = state;
|
|
1053
|
-
},
|
|
1054
|
-
onProvisioningStart() {
|
|
1055
|
-
telegramTopicProvisioningCount += 1;
|
|
1056
|
-
},
|
|
1057
|
-
onProvisioningEnd() {
|
|
1058
|
-
telegramTopicProvisioningCount = Math.max(
|
|
1059
|
-
0,
|
|
1060
|
-
telegramTopicProvisioningCount - 1,
|
|
1061
|
-
);
|
|
1062
|
-
},
|
|
1063
|
-
recordRuntimeEvent,
|
|
1064
|
-
}),
|
|
1065
|
-
restoreFollowerRegistry:
|
|
1066
|
-
BusLeader.createTelegramBusFollowerRegistryRestoreHandler({
|
|
1067
|
-
topicTargetStore: threadStore,
|
|
1068
|
-
followerRegistry: telegramBusFollowerRegistry,
|
|
1069
|
-
recordRuntimeEvent,
|
|
1070
|
-
}),
|
|
1071
|
-
callApi: BusLeader.createTelegramBusLeaderApiProxy({
|
|
1072
|
-
call: directTelegramApiRuntime.call,
|
|
1073
|
-
callMultipart: directTelegramApiRuntime.callMultipart,
|
|
1074
|
-
downloadFile: directTelegramApiRuntime.downloadFile,
|
|
1075
|
-
recoverStaleTargetError: recoverStaleTelegramTopicApiError,
|
|
1076
|
-
}),
|
|
1077
|
-
recordRuntimeEvent,
|
|
1078
|
-
});
|
|
1008
|
+
});
|
|
1079
1009
|
let pollingStartedWithTelegramBus = false;
|
|
1080
1010
|
let forceFreshLeaderThreadOnNextStart = false;
|
|
1081
1011
|
const telegramLeaderHealthRuntime = Sync.createTelegramLeaderHealthRuntime({
|
package/lib/bindings.ts
CHANGED
|
@@ -94,7 +94,9 @@ export function registerTelegramCommandsAndTools({
|
|
|
94
94
|
sendMarkdownReply(chatId, undefined, markdown, options),
|
|
95
95
|
recordRuntimeEvent,
|
|
96
96
|
});
|
|
97
|
-
Prompts.registerTelegramHelpTool(pi
|
|
97
|
+
Prompts.registerTelegramHelpTool(pi, {
|
|
98
|
+
getActiveProfileName: configStore.getActiveProfileName,
|
|
99
|
+
});
|
|
98
100
|
Commands.registerTelegramBridgeCommands(pi, {
|
|
99
101
|
promptForConfig: async (ctx, profileName) => {
|
|
100
102
|
const nextProfileName = profileName ?? undefined;
|
|
@@ -103,36 +105,58 @@ export function registerTelegramCommandsAndTools({
|
|
|
103
105
|
return;
|
|
104
106
|
}
|
|
105
107
|
const previousProfileName = configStore.getActiveProfileName();
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
108
|
+
let setupConfigStore = configStore;
|
|
109
|
+
let persistSetupConfig = persistConfig;
|
|
109
110
|
if (!profileName) {
|
|
111
|
+
if (previousProfileName !== nextProfileName) {
|
|
112
|
+
await (stopPolling ?? lockedPollingRuntime.stop)();
|
|
113
|
+
}
|
|
110
114
|
configStore.activateProfile(undefined);
|
|
111
115
|
} else {
|
|
112
116
|
const storedConfig = configStore.getStoredConfig();
|
|
113
|
-
|
|
117
|
+
setupConfigStore = Config.createTelegramConfigStore({
|
|
118
|
+
initialConfig: {
|
|
119
|
+
...storedConfig,
|
|
120
|
+
profiles: {
|
|
121
|
+
...(storedConfig.profiles ?? {}),
|
|
122
|
+
[profileName]: storedConfig.profiles?.[profileName] ?? {
|
|
123
|
+
botToken: "",
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
setupConfigStore.activateProfile(profileName);
|
|
129
|
+
persistSetupConfig = async () => {
|
|
130
|
+
if (previousProfileName !== profileName) {
|
|
131
|
+
await (stopPolling ?? lockedPollingRuntime.stop)();
|
|
132
|
+
}
|
|
133
|
+
configStore.activateProfile(undefined);
|
|
114
134
|
configStore.set({
|
|
115
135
|
...storedConfig,
|
|
116
136
|
profiles: {
|
|
117
137
|
...(storedConfig.profiles ?? {}),
|
|
118
|
-
[profileName]:
|
|
138
|
+
[profileName]: storedConfig.profiles?.[profileName] ?? {
|
|
139
|
+
botToken: "",
|
|
140
|
+
},
|
|
119
141
|
},
|
|
120
142
|
});
|
|
121
|
-
|
|
122
|
-
|
|
143
|
+
configStore.activateProfile(profileName);
|
|
144
|
+
configStore.set(setupConfigStore.get());
|
|
145
|
+
await persistConfig();
|
|
146
|
+
};
|
|
123
147
|
}
|
|
124
148
|
const runSetup = Setup.createTelegramSetupPromptRuntime({
|
|
125
|
-
getConfig:
|
|
126
|
-
setConfig:
|
|
149
|
+
getConfig: setupConfigStore.get,
|
|
150
|
+
setConfig: setupConfigStore.set,
|
|
127
151
|
setupGuard: setup,
|
|
128
152
|
getMe: TelegramApi.fetchTelegramBotIdentity,
|
|
129
|
-
persistConfig,
|
|
153
|
+
persistConfig: persistSetupConfig,
|
|
130
154
|
startPolling: lockedPollingRuntime.start,
|
|
131
155
|
updateStatus,
|
|
132
156
|
recordRuntimeEvent,
|
|
133
157
|
});
|
|
134
|
-
await runSetup(ctx);
|
|
135
|
-
if (profileName) {
|
|
158
|
+
const completion = await runSetup(ctx);
|
|
159
|
+
if (profileName && completion.status === "success") {
|
|
136
160
|
ctx.ui.notify(`Profile "${profileName}" saved and connected.`, "info");
|
|
137
161
|
}
|
|
138
162
|
},
|
|
@@ -155,6 +179,8 @@ export function registerTelegramCommandsAndTools({
|
|
|
155
179
|
activateProfileConfig: async (_ctx, profileName) => {
|
|
156
180
|
await configStore.load();
|
|
157
181
|
if (!Config.isValidTelegramProfileName(profileName)) return false;
|
|
182
|
+
const storedConfig = configStore.getStoredConfig();
|
|
183
|
+
if (!storedConfig.profiles?.[profileName]) return false;
|
|
158
184
|
const previousProfileName = configStore.getActiveProfileName();
|
|
159
185
|
if (previousProfileName !== profileName) {
|
|
160
186
|
await (stopPolling ?? lockedPollingRuntime.stop)();
|