@ouro.bot/cli 0.1.0-alpha.51 → 0.1.0-alpha.53

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.
@@ -40,6 +40,7 @@ exports.createTeamsCallbacks = createTeamsCallbacks;
40
40
  exports.resolvePendingConfirmation = resolvePendingConfirmation;
41
41
  exports.withConversationLock = withConversationLock;
42
42
  exports.handleTeamsMessage = handleTeamsMessage;
43
+ exports.sendProactiveTeamsMessageToSession = sendProactiveTeamsMessageToSession;
43
44
  exports.drainAndSendPendingTeams = drainAndSendPendingTeams;
44
45
  exports.startTeamsApp = startTeamsApp;
45
46
  const fs = __importStar(require("fs"));
@@ -867,6 +868,98 @@ function findAadObjectId(friend) {
867
868
  }
868
869
  return undefined;
869
870
  }
871
+ function resolveTeamsFriendStore(deps) {
872
+ return deps.store
873
+ ?? deps.createFriendStore?.()
874
+ ?? new store_file_1.FileFriendStore(path.join((0, identity_1.getAgentRoot)(), "friends"));
875
+ }
876
+ function getTeamsConversations(botApi) {
877
+ return botApi.conversations;
878
+ }
879
+ function hasExplicitCrossChatAuthorization(params) {
880
+ return params.intent === "explicit_cross_chat"
881
+ && types_1.TRUSTED_LEVELS.has(params.authorizingSession?.trustLevel ?? "stranger");
882
+ }
883
+ async function sendProactiveTeamsMessageToSession(params, deps) {
884
+ const store = resolveTeamsFriendStore(deps);
885
+ const conversations = getTeamsConversations(deps.botApi);
886
+ let friend;
887
+ try {
888
+ friend = await store.get(params.friendId);
889
+ }
890
+ catch {
891
+ friend = null;
892
+ }
893
+ if (!friend) {
894
+ (0, runtime_1.emitNervesEvent)({
895
+ level: "warn",
896
+ component: "senses",
897
+ event: "senses.teams_proactive_no_friend",
898
+ message: "proactive send skipped: friend not found",
899
+ meta: { friendId: params.friendId, sessionKey: params.sessionKey },
900
+ });
901
+ return { delivered: false, reason: "friend_not_found" };
902
+ }
903
+ if (!hasExplicitCrossChatAuthorization(params) && !types_1.TRUSTED_LEVELS.has(friend.trustLevel ?? "stranger")) {
904
+ (0, runtime_1.emitNervesEvent)({
905
+ component: "senses",
906
+ event: "senses.teams_proactive_trust_skip",
907
+ message: "proactive send skipped: trust level not allowed",
908
+ meta: {
909
+ friendId: params.friendId,
910
+ trustLevel: friend.trustLevel ?? "unknown",
911
+ intent: params.intent ?? "generic_outreach",
912
+ authorizingTrustLevel: params.authorizingSession?.trustLevel ?? null,
913
+ },
914
+ });
915
+ return { delivered: false, reason: "trust_skip" };
916
+ }
917
+ const aadInfo = findAadObjectId(friend);
918
+ if (!aadInfo) {
919
+ (0, runtime_1.emitNervesEvent)({
920
+ level: "warn",
921
+ component: "senses",
922
+ event: "senses.teams_proactive_no_aad_id",
923
+ message: "proactive send skipped: no AAD object ID found",
924
+ meta: { friendId: params.friendId, sessionKey: params.sessionKey },
925
+ });
926
+ return { delivered: false, reason: "missing_target" };
927
+ }
928
+ try {
929
+ const conversation = await conversations.create({
930
+ bot: { id: deps.botApi.id },
931
+ members: [{ id: aadInfo.aadObjectId, role: "user", name: friend.name || aadInfo.aadObjectId }],
932
+ tenantId: aadInfo.tenantId,
933
+ isGroup: false,
934
+ });
935
+ await conversations.activities(conversation.id).create({
936
+ type: "message",
937
+ text: params.text,
938
+ });
939
+ (0, runtime_1.emitNervesEvent)({
940
+ component: "senses",
941
+ event: "senses.teams_proactive_sent",
942
+ message: "proactive teams message sent",
943
+ meta: { friendId: params.friendId, aadObjectId: aadInfo.aadObjectId, sessionKey: params.sessionKey },
944
+ });
945
+ return { delivered: true };
946
+ }
947
+ catch (error) {
948
+ (0, runtime_1.emitNervesEvent)({
949
+ level: "error",
950
+ component: "senses",
951
+ event: "senses.teams_proactive_send_error",
952
+ message: "proactive teams send failed",
953
+ meta: {
954
+ friendId: params.friendId,
955
+ aadObjectId: aadInfo.aadObjectId,
956
+ sessionKey: params.sessionKey,
957
+ reason: error instanceof Error ? error.message : String(error),
958
+ },
959
+ });
960
+ return { delivered: false, reason: "send_error" };
961
+ }
962
+ }
870
963
  function scanPendingTeamsFiles(pendingRoot) {
871
964
  const results = [];
872
965
  let friendIds;
@@ -912,8 +1005,7 @@ async function drainAndSendPendingTeams(store, botApi, pendingRoot) {
912
1005
  const root = pendingRoot ?? path.join((0, identity_1.getAgentRoot)(), "state", "pending");
913
1006
  const pendingFiles = scanPendingTeamsFiles(root);
914
1007
  const result = { sent: 0, skipped: 0, failed: 0 };
915
- const conversations = botApi.conversations;
916
- for (const { friendId, filePath, content } of pendingFiles) {
1008
+ for (const { friendId, key, filePath, content } of pendingFiles) {
917
1009
  let parsed;
918
1010
  try {
919
1011
  parsed = JSON.parse(content);
@@ -935,95 +1027,32 @@ async function drainAndSendPendingTeams(store, botApi, pendingRoot) {
935
1027
  catch { /* ignore */ }
936
1028
  continue;
937
1029
  }
938
- let friend;
939
- try {
940
- friend = await store.get(friendId);
941
- }
942
- catch {
943
- friend = null;
944
- }
945
- if (!friend) {
946
- result.skipped++;
947
- try {
948
- fs.unlinkSync(filePath);
949
- }
950
- catch { /* ignore */ }
951
- (0, runtime_1.emitNervesEvent)({
952
- level: "warn",
953
- component: "senses",
954
- event: "senses.teams_proactive_no_friend",
955
- message: "proactive send skipped: friend not found",
956
- meta: { friendId },
957
- });
958
- continue;
959
- }
960
- if (!types_1.TRUSTED_LEVELS.has(friend.trustLevel ?? "stranger")) {
961
- result.skipped++;
1030
+ const sendResult = await sendProactiveTeamsMessageToSession({
1031
+ friendId,
1032
+ sessionKey: key,
1033
+ text: messageText,
1034
+ intent: "generic_outreach",
1035
+ }, {
1036
+ botApi,
1037
+ store,
1038
+ });
1039
+ if (sendResult.delivered) {
1040
+ result.sent++;
962
1041
  try {
963
1042
  fs.unlinkSync(filePath);
964
1043
  }
965
1044
  catch { /* ignore */ }
966
- (0, runtime_1.emitNervesEvent)({
967
- component: "senses",
968
- event: "senses.teams_proactive_trust_skip",
969
- message: "proactive send skipped: trust level not allowed",
970
- meta: { friendId, trustLevel: friend.trustLevel ?? "unknown" },
971
- });
972
1045
  continue;
973
1046
  }
974
- const aadInfo = findAadObjectId(friend);
975
- if (!aadInfo) {
1047
+ if (sendResult.reason === "friend_not_found" || sendResult.reason === "trust_skip" || sendResult.reason === "missing_target") {
976
1048
  result.skipped++;
977
1049
  try {
978
1050
  fs.unlinkSync(filePath);
979
1051
  }
980
1052
  catch { /* ignore */ }
981
- (0, runtime_1.emitNervesEvent)({
982
- level: "warn",
983
- component: "senses",
984
- event: "senses.teams_proactive_no_aad_id",
985
- message: "proactive send skipped: no AAD object ID found",
986
- meta: { friendId },
987
- });
988
1053
  continue;
989
1054
  }
990
- try {
991
- const conversation = await conversations.create({
992
- bot: { id: botApi.id },
993
- members: [{ id: aadInfo.aadObjectId, role: "user", name: friend.name || aadInfo.aadObjectId }],
994
- tenantId: aadInfo.tenantId,
995
- isGroup: false,
996
- });
997
- await conversations.activities(conversation.id).create({
998
- type: "message",
999
- text: messageText,
1000
- });
1001
- result.sent++;
1002
- try {
1003
- fs.unlinkSync(filePath);
1004
- }
1005
- catch { /* ignore */ }
1006
- (0, runtime_1.emitNervesEvent)({
1007
- component: "senses",
1008
- event: "senses.teams_proactive_sent",
1009
- message: "proactive teams message sent",
1010
- meta: { friendId, aadObjectId: aadInfo.aadObjectId },
1011
- });
1012
- }
1013
- catch (error) {
1014
- result.failed++;
1015
- (0, runtime_1.emitNervesEvent)({
1016
- level: "error",
1017
- component: "senses",
1018
- event: "senses.teams_proactive_send_error",
1019
- message: "proactive teams send failed",
1020
- meta: {
1021
- friendId,
1022
- aadObjectId: aadInfo.aadObjectId,
1023
- reason: error instanceof Error ? error.message : String(error),
1024
- },
1025
- });
1026
- }
1055
+ result.failed++;
1027
1056
  }
1028
1057
  if (result.sent > 0 || result.skipped > 0 || result.failed > 0) {
1029
1058
  (0, runtime_1.emitNervesEvent)({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.51",
3
+ "version": "0.1.0-alpha.53",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",