@ouro.bot/cli 0.1.0-alpha.815 → 0.1.0-alpha.817
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/assets/sanctuary-host-launcher.sh +16 -0
- package/changelog.json +18 -0
- package/deploy/unraid/Dockerfile +6 -0
- package/deploy/unraid/README.txt +305 -365
- package/deploy/unraid/docker-man-template-transaction.mjs +192 -7
- package/deploy/unraid/sanctuary-acceptance-adapter.sh +1 -1
- package/deploy/unraid/sanctuary-acceptance-contract.json +7 -7
- package/deploy/unraid/sanctuary-authority-installation.json +36 -0
- package/deploy/unraid/sanctuary-authority-service.sh +30 -0
- package/deploy/unraid/sanctuary-unit16-host-broker.mjs +62 -9
- package/deploy/unraid/sanctuary-unit16-run.sh +15 -15
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +1 -1
- package/deploy/unraid/sanctuary.ouro/tool-profiles.json +2 -2
- package/deploy/unraid/sanctuary.xml +2 -1
- package/dist/heart/approval-store.js +11 -1
- package/dist/heart/core.js +2 -1
- package/dist/heart/daemon/container-spec-auditor-main.js +9 -8
- package/dist/heart/daemon/container-spec-auditor.js +17 -24
- package/dist/heart/daemon/sanctuary-acceptance-adapter.js +95 -91
- package/dist/heart/daemon/sanctuary-acceptance-harness.js +95 -169
- package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +4 -5
- package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
- package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
- package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
- package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
- package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +780 -0
- package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
- package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
- package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
- package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
- package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
- package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
- package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-service.js +615 -0
- package/dist/heart/daemon/sense-manager.js +20 -10
- package/dist/heart/external-events/router.js +31 -15
- package/dist/heart/steward-policy.js +374 -58
- package/dist/heart/tool-approval.js +8 -1
- package/dist/repertoire/relationship-authorization.js +128 -0
- package/dist/repertoire/tools-base.js +9 -13
- package/dist/repertoire/tools-sanctuary-host.js +202 -0
- package/dist/repertoire/tools-steward-policy.js +34 -10
- package/dist/repertoire/tools-unraid.js +79 -32
- package/dist/repertoire/tools.js +37 -25
- package/dist/repertoire/unraid-restart.js +179 -52
- package/dist/senses/private-runtime.js +27 -12
- package/dist/senses/root-host-approval-port.js +345 -0
- package/dist/senses/root-host-approval-runtime.js +393 -0
- package/dist/senses/sanctuary-authority-resident.js +102 -0
- package/dist/senses/sanctuary-health-runner.js +0 -1
- package/dist/senses/sanctuary-media-catalog-contract.js +4 -1
- package/dist/senses/sanctuary-runtime.js +2 -0
- package/dist/senses/telegram-admission.js +7 -0
- package/dist/senses/telegram-approval-runtime.js +130 -12
- package/dist/senses/telegram-attachments.js +5 -1
- package/dist/senses/telegram-authority-transport.js +231 -0
- package/dist/senses/telegram-client.js +31 -8
- package/dist/senses/telegram-entry.js +1 -1
- package/dist/senses/telegram.js +174 -28
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/senses/telegram.js
CHANGED
|
@@ -69,6 +69,9 @@ const sanctuary_download_credit_presentation_1 = require("./sanctuary-download-c
|
|
|
69
69
|
const shared_turn_1 = require("./shared-turn");
|
|
70
70
|
const config_1 = require("../heart/config");
|
|
71
71
|
const telegram_client_1 = require("./telegram-client");
|
|
72
|
+
const sanctuary_authority_resident_1 = require("./sanctuary-authority-resident");
|
|
73
|
+
const root_host_approval_runtime_1 = require("./root-host-approval-runtime");
|
|
74
|
+
const tools_sanctuary_host_1 = require("../repertoire/tools-sanctuary-host");
|
|
72
75
|
const sanctuary_runtime_2 = require("./sanctuary-runtime");
|
|
73
76
|
const sanctuary_full_visibility_contract_1 = require("./sanctuary-full-visibility-contract");
|
|
74
77
|
const sanctuary_install_state_contract_1 = require("./sanctuary-install-state-contract");
|
|
@@ -671,8 +674,10 @@ function migrateTelegramSessionIdentity(agentRoot, legacyUserId, legacyChatId, s
|
|
|
671
674
|
}
|
|
672
675
|
function redactTelegramPrivateValues(error, privateValues) {
|
|
673
676
|
let message = error instanceof Error ? error.message : String(error);
|
|
674
|
-
for (const privateValue of privateValues)
|
|
675
|
-
|
|
677
|
+
for (const privateValue of privateValues) {
|
|
678
|
+
if (privateValue)
|
|
679
|
+
message = message.split(privateValue).join("[redacted]");
|
|
680
|
+
}
|
|
676
681
|
return message;
|
|
677
682
|
}
|
|
678
683
|
function parseTelegramSenseCredentials(value) {
|
|
@@ -683,10 +688,25 @@ function parseTelegramSenseCredentials(value) {
|
|
|
683
688
|
};
|
|
684
689
|
}
|
|
685
690
|
function createTelegramSenseApp(options) {
|
|
686
|
-
const
|
|
691
|
+
const authorityTransport = options.authorityTransport;
|
|
692
|
+
if (authorityTransport && options.agentName !== "sanctuary") {
|
|
693
|
+
throw new Error("Sanctuary Telegram authority transport cannot serve another agent");
|
|
694
|
+
}
|
|
695
|
+
if (authorityTransport && options.credentials.botToken !== undefined) {
|
|
696
|
+
throw new Error("Sanctuary Telegram authority transport forbids a resident bot token");
|
|
697
|
+
}
|
|
698
|
+
const botToken = options.credentials.botToken === undefined
|
|
699
|
+
? null
|
|
700
|
+
: requiredText(options.credentials.botToken, "bot token");
|
|
701
|
+
if (!botToken && !authorityTransport) {
|
|
702
|
+
throw new Error("Telegram bot token is missing; Sanctuary requires an explicit gateway transport");
|
|
703
|
+
}
|
|
687
704
|
const botId = options.credentials.botId !== undefined
|
|
688
705
|
? canonicalTelegramId(options.credentials.botId, "bot id")
|
|
689
|
-
: options.admission ? telegramBotIdFromToken(botToken) : null;
|
|
706
|
+
: options.admission && botToken ? telegramBotIdFromToken(botToken) : null;
|
|
707
|
+
if (authorityTransport && botId === null) {
|
|
708
|
+
throw new Error("Sanctuary Telegram authority transport requires a pinned bot id");
|
|
709
|
+
}
|
|
690
710
|
const authorizedUserId = canonicalTelegramId(options.credentials.authorizedUserId, "authorized user id");
|
|
691
711
|
const authorizedChatId = canonicalTelegramId(options.credentials.authorizedChatId, "authorized chat id");
|
|
692
712
|
const agentRoot = options._agentRoot ?? (0, identity_1.getAgentRoot)(options.agentName);
|
|
@@ -694,8 +714,9 @@ function createTelegramSenseApp(options) {
|
|
|
694
714
|
? readOrCreateTelegramIdentityKey(agentRoot)
|
|
695
715
|
: canonicalTelegramIdentityKey(options.identityKey);
|
|
696
716
|
const subject = opaqueTelegramSubject(identityKey, botId ?? botToken, authorizedUserId, authorizedChatId);
|
|
697
|
-
const
|
|
698
|
-
const
|
|
717
|
+
const transportPrivateValues = [botToken ?? "", authorizedUserId, authorizedChatId];
|
|
718
|
+
const transportError = (error) => redactTelegramPrivateValues(error, transportPrivateValues);
|
|
719
|
+
const api = authorityTransport?.api ?? options.api ?? (0, telegram_client_1.createTelegramBotApi)({ token: botToken });
|
|
699
720
|
const offsetStore = options.offsetStore ?? new telegram_client_1.FileTelegramOffsetStore(path.join(agentRoot, "state", "senses", "telegram", "offset.json"));
|
|
700
721
|
const inboxStore = options.inboxStore ?? new telegram_client_1.FileTelegramUpdateInboxStore(path.join(agentRoot, "state", "senses", "telegram", "inbox.json"));
|
|
701
722
|
const admissionStore = options.admission
|
|
@@ -752,11 +773,11 @@ function createTelegramSenseApp(options) {
|
|
|
752
773
|
if (!/^[0-9a-f]{64}$/u.test(scenarioHandleDigest))
|
|
753
774
|
throw new Error("Telegram acceptance audit scenario handle is invalid");
|
|
754
775
|
if (!acceptanceAuditLease) {
|
|
755
|
-
acceptanceAuditLease = acquireTelegramAcceptanceAudit(options.acceptanceReceiptRoot ?? agentRoot, options.agentName, identityKey,
|
|
776
|
+
acceptanceAuditLease = acquireTelegramAcceptanceAudit(options.acceptanceReceiptRoot ?? agentRoot, options.agentName, identityKey, transportPrivateValues, scenarioHandleDigest, options._acceptanceAuditReleaseHook, options._acceptanceAuditMaxBytes);
|
|
756
777
|
}
|
|
757
778
|
else if (scenarioHandleDigest !== acceptanceAuditLease.scenarioHandleDigest) {
|
|
758
779
|
retireAcceptanceAudit();
|
|
759
|
-
acceptanceAuditLease = acquireTelegramAcceptanceAudit(options.acceptanceReceiptRoot ?? agentRoot, options.agentName, identityKey,
|
|
780
|
+
acceptanceAuditLease = acquireTelegramAcceptanceAudit(options.acceptanceReceiptRoot ?? agentRoot, options.agentName, identityKey, transportPrivateValues, scenarioHandleDigest, options._acceptanceAuditReleaseHook, options._acceptanceAuditMaxBytes);
|
|
760
781
|
}
|
|
761
782
|
return acceptanceAuditLease;
|
|
762
783
|
};
|
|
@@ -847,6 +868,17 @@ function createTelegramSenseApp(options) {
|
|
|
847
868
|
};
|
|
848
869
|
let effectJournal;
|
|
849
870
|
let approvalRuntime;
|
|
871
|
+
let rootHostRuntime;
|
|
872
|
+
const approvalCoordinatorFactory = (context) => ({
|
|
873
|
+
propose: (request) => {
|
|
874
|
+
if (request.toolCall.type === "function" && request.toolCall.function.name === "sanctuary_host_execute") {
|
|
875
|
+
if (!rootHostRuntime)
|
|
876
|
+
throw new Error("root host approval coordinator is unavailable");
|
|
877
|
+
return rootHostRuntime.coordinator(context).propose(request);
|
|
878
|
+
}
|
|
879
|
+
return approvalRuntime.coordinator(context).propose(request);
|
|
880
|
+
},
|
|
881
|
+
});
|
|
850
882
|
const getEffectJournal = () => {
|
|
851
883
|
effectJournal ??= new telegram_effect_adapter_1.FileTelegramEffectJournal(path.join(agentRoot, "state", "telegram", "effects"));
|
|
852
884
|
return effectJournal;
|
|
@@ -913,6 +945,12 @@ function createTelegramSenseApp(options) {
|
|
|
913
945
|
subject,
|
|
914
946
|
identityKey,
|
|
915
947
|
toolContext: toolContext ?? {},
|
|
948
|
+
...(options.resolveRelationshipAuthorization ? {
|
|
949
|
+
resolveOwnerRelationship: (binding) => options.resolveRelationshipAuthorization({
|
|
950
|
+
friendId: binding.friendId, requestId: binding.requestId, sessionEventId: binding.sessionEventId, sessionKey: binding.sessionKey,
|
|
951
|
+
botId: botId, userId: authorizedUserId, chatId: authorizedChatId,
|
|
952
|
+
}),
|
|
953
|
+
} : {}),
|
|
916
954
|
resolveLiveToolContext: async (record) => {
|
|
917
955
|
const sessionPath = (0, shared_turn_1.getSenseSessionPath)(options.agentName, configuredOwnerFriendId, "telegram", configuredOwnerSessionKey, agentRoot);
|
|
918
956
|
if (record.transport !== "telegram" || record.requesterId !== subject
|
|
@@ -953,6 +991,40 @@ function createTelegramSenseApp(options) {
|
|
|
953
991
|
},
|
|
954
992
|
}) : undefined);
|
|
955
993
|
approvalTransport = options.approvalTransport ?? approvalRuntime?.transport;
|
|
994
|
+
const port = authorityTransport?.hostApproval;
|
|
995
|
+
if (useSanctuaryRuntime && port?.pins.expectedBotId === botId
|
|
996
|
+
&& port.pins.expectedOwnerUserId === authorizedUserId && port.pins.expectedOwnerChatId === authorizedChatId) {
|
|
997
|
+
rootHostRuntime = (0, root_host_approval_runtime_1.createRootHostApprovalRuntime)({
|
|
998
|
+
agentRoot, port, effectBarrier: acceptanceAuditBarrier, approvalCoordinatorFactory,
|
|
999
|
+
resolveContext: async (binding) => {
|
|
1000
|
+
const sessionPath = (0, shared_turn_1.getSenseSessionPath)(options.agentName, configuredOwnerFriendId, "telegram", configuredOwnerSessionKey, agentRoot);
|
|
1001
|
+
if (binding.agentRoot !== agentRoot || binding.friendId !== configuredOwnerFriendId
|
|
1002
|
+
|| binding.sessionKey !== configuredOwnerSessionKey || binding.sessionPath !== sessionPath) {
|
|
1003
|
+
throw new Error("root host continuation owner session changed");
|
|
1004
|
+
}
|
|
1005
|
+
const relationshipAuthorization = await resolveLiveRelationshipAuthorization({
|
|
1006
|
+
friendId: binding.friendId, requestId: binding.requestId, sessionEventId: binding.sessionEventId,
|
|
1007
|
+
sessionKey: binding.sessionKey, botId: botId, userId: authorizedUserId, chatId: authorizedChatId,
|
|
1008
|
+
});
|
|
1009
|
+
const friendStore = new friends_1.FileFriendStore(path.join(agentRoot, "friends"));
|
|
1010
|
+
const friend = await friendStore.get(binding.friendId);
|
|
1011
|
+
if (!friend)
|
|
1012
|
+
throw new Error("root host owner Friend is unavailable");
|
|
1013
|
+
return {
|
|
1014
|
+
...toolContext, signin: async () => undefined, agentName: options.agentName, agentRoot,
|
|
1015
|
+
currentSession: { friendId: friend.id, channel: "telegram", key: binding.sessionKey, sessionPath },
|
|
1016
|
+
context: { friend, channel: (0, friends_1.getChannelCapabilities)("telegram") }, friendStore, relationshipAuthorization,
|
|
1017
|
+
rootHost: { port },
|
|
1018
|
+
};
|
|
1019
|
+
},
|
|
1020
|
+
deliver: async (text, approvalId) => {
|
|
1021
|
+
await approvalEffects.sendText({
|
|
1022
|
+
idempotencyKey: `root-host:${approvalId}:continuation:${(0, node_crypto_1.createHash)("sha256").update(text).digest("hex")}`,
|
|
1023
|
+
chatId: authorizedChatId, text, authorClass: "butler",
|
|
1024
|
+
});
|
|
1025
|
+
},
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
956
1028
|
interactiveControl = useSanctuaryRuntime && approvalTransport
|
|
957
1029
|
? (options._createInteractiveControl ?? sanctuary_interactive_control_1.createSanctuaryInteractiveControl)({
|
|
958
1030
|
agentRoot,
|
|
@@ -1014,7 +1086,10 @@ function createTelegramSenseApp(options) {
|
|
|
1014
1086
|
approvalReconcileTimer = setTimeout(() => {
|
|
1015
1087
|
approvalReconcileTimer = undefined;
|
|
1016
1088
|
scheduleApprovalReconcile();
|
|
1017
|
-
const reconciliation = runWithAcceptanceAuditOwner(
|
|
1089
|
+
const reconciliation = runWithAcceptanceAuditOwner(async () => {
|
|
1090
|
+
await approvalTransport.reconcileExpired();
|
|
1091
|
+
await rootHostRuntime?.recover();
|
|
1092
|
+
}).catch((error) => {
|
|
1018
1093
|
acceptanceAuditBarrier();
|
|
1019
1094
|
(0, runtime_1.emitNervesEvent)({
|
|
1020
1095
|
level: "error",
|
|
@@ -1179,10 +1254,20 @@ function createTelegramSenseApp(options) {
|
|
|
1179
1254
|
},
|
|
1180
1255
|
validateTerminalAnswer: (answer) => contracts.map((contract) => contract.validateTerminalAnswer?.(answer)).find((rejection) => rejection !== undefined),
|
|
1181
1256
|
};
|
|
1257
|
+
const currentToolContext = { ...runAgentOptions.toolContext, relationshipAuthorization };
|
|
1258
|
+
if (isSanctuaryOwner && rootHostRuntime && input.authority && await authorityTransport.hostApproval.refresh()) {
|
|
1259
|
+
currentToolContext.rootHost = { port: authorityTransport.hostApproval, observation: input.authority };
|
|
1260
|
+
try {
|
|
1261
|
+
await (0, tools_sanctuary_host_1.authorizeRootHostContext)(currentToolContext);
|
|
1262
|
+
}
|
|
1263
|
+
catch {
|
|
1264
|
+
delete currentToolContext.rootHost;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1182
1267
|
return {
|
|
1183
1268
|
...runAgentOptions,
|
|
1184
1269
|
...(requiredToolCalls ? { requiredToolCalls } : {}),
|
|
1185
|
-
toolContext:
|
|
1270
|
+
toolContext: currentToolContext,
|
|
1186
1271
|
};
|
|
1187
1272
|
};
|
|
1188
1273
|
};
|
|
@@ -1272,6 +1357,15 @@ function createTelegramSenseApp(options) {
|
|
|
1272
1357
|
},
|
|
1273
1358
|
claimFriend: options.admission.claimFriend,
|
|
1274
1359
|
revokeFriend: options.admission.revokeFriend,
|
|
1360
|
+
...(authorityTransport ? {
|
|
1361
|
+
registerCommunication: (input) => authorityTransport.admitChat({
|
|
1362
|
+
admissionId: input.id,
|
|
1363
|
+
updateId: input.updateId,
|
|
1364
|
+
userId: input.userId,
|
|
1365
|
+
chatId: input.chatId,
|
|
1366
|
+
}),
|
|
1367
|
+
revokeCommunication: (input) => authorityTransport.revokeChat(input),
|
|
1368
|
+
} : {}),
|
|
1275
1369
|
commitApprovedIngress: async (input) => {
|
|
1276
1370
|
const sessionKey = `telegram:${input.botId}:${input.userId}`;
|
|
1277
1371
|
const reference = `telegram-admission:${input.admissionId}`;
|
|
@@ -1332,8 +1426,9 @@ function createTelegramSenseApp(options) {
|
|
|
1332
1426
|
const ingested = await (0, telegram_attachments_1.ingestTelegramAttachments)({
|
|
1333
1427
|
agentName: options.agentName,
|
|
1334
1428
|
agentRoot,
|
|
1335
|
-
botToken,
|
|
1429
|
+
...(botToken ? { botToken } : {}),
|
|
1336
1430
|
api,
|
|
1431
|
+
...(authorityTransport ? { downloadFile: authorityTransport.downloadFile } : {}),
|
|
1337
1432
|
...(options.attachmentFetch ? { fetch: options.attachmentFetch } : {}),
|
|
1338
1433
|
attachments: message.attachments ?? [],
|
|
1339
1434
|
});
|
|
@@ -1453,10 +1548,11 @@ function createTelegramSenseApp(options) {
|
|
|
1453
1548
|
chatId: message.chatId,
|
|
1454
1549
|
sessionKey: currentSessionKey,
|
|
1455
1550
|
userMessage: message.text,
|
|
1551
|
+
authority: message.authority,
|
|
1456
1552
|
fullVisibilityProgress: fullVisibility.progress,
|
|
1457
1553
|
}),
|
|
1458
1554
|
} : {}),
|
|
1459
|
-
...(approvalRuntime ? { approvalCoordinatorFactory: approvalRuntime.coordinator } : {}),
|
|
1555
|
+
...(approvalRuntime ? { approvalCoordinatorFactory: rootHostRuntime ? approvalCoordinatorFactory : approvalRuntime.coordinator } : {}),
|
|
1460
1556
|
}), toolReceiptObserver);
|
|
1461
1557
|
const result = collected.result;
|
|
1462
1558
|
let responseFallbackArtifactId;
|
|
@@ -1511,9 +1607,9 @@ function createTelegramSenseApp(options) {
|
|
|
1511
1607
|
...lifecycleCoordinates,
|
|
1512
1608
|
...(acceptanceMarker ? {
|
|
1513
1609
|
outcome: "error",
|
|
1514
|
-
errorDigest: auditDigest("error", redactTelegramPrivateValues(error, [
|
|
1610
|
+
errorDigest: auditDigest("error", redactTelegramPrivateValues(error, [...transportPrivateValues, String(message.updateId), message.messageId])),
|
|
1515
1611
|
deliveryCount: deliveredMessageIds.length,
|
|
1516
|
-
} : { error: redactTelegramPrivateValues(error, [
|
|
1612
|
+
} : { error: redactTelegramPrivateValues(error, [...transportPrivateValues, String(message.updateId), message.messageId]) }),
|
|
1517
1613
|
}, Math.max(Date.now(), lifecycleStartedAt + 1)),
|
|
1518
1614
|
});
|
|
1519
1615
|
const fallback = "I couldn't complete that turn. The failure was recorded; please try again.";
|
|
@@ -1527,7 +1623,7 @@ function createTelegramSenseApp(options) {
|
|
|
1527
1623
|
const grounded = groundedAcceptance;
|
|
1528
1624
|
const schemaVersion = grounded ? "sanctuary-telegram-turn-receipt-v4" : "sanctuary-telegram-turn-receipt-v3";
|
|
1529
1625
|
const hmac = (purpose, value) => sanctuaryTelegramTurnReceiptDigest(identityKey, schemaVersion, purpose, value);
|
|
1530
|
-
const redact = (value) => [
|
|
1626
|
+
const redact = (value) => [...transportPrivateValues, String(message.updateId), message.messageId]
|
|
1531
1627
|
.reduce((text, privateValue) => privateValue.length >= 5 ? text.replaceAll(privateValue, "[REDACTED]") : text, value);
|
|
1532
1628
|
const deliveries = deliveredMessageIds.map((messageId, index) => {
|
|
1533
1629
|
const chunk = deliveredChunks[index];
|
|
@@ -1586,6 +1682,13 @@ function createTelegramSenseApp(options) {
|
|
|
1586
1682
|
await admissionController.handleUnknown(message);
|
|
1587
1683
|
return;
|
|
1588
1684
|
}
|
|
1685
|
+
// Existing household Friends need a root-observed communication binding after gateway migration.
|
|
1686
|
+
await authorityTransport?.admitChat({
|
|
1687
|
+
admissionId: (0, node_crypto_1.createHash)("sha256").update(`telegram-communication-v1\0${message.botId}\0${message.userId}\0${message.chatId}`).digest("hex").slice(0, 20),
|
|
1688
|
+
updateId: message.updateId,
|
|
1689
|
+
userId: message.userId,
|
|
1690
|
+
chatId: message.chatId,
|
|
1691
|
+
});
|
|
1589
1692
|
const hydrated = await hydrateAuthorizedMessage({
|
|
1590
1693
|
updateId: message.updateId,
|
|
1591
1694
|
messageId: String(message.messageId),
|
|
@@ -1604,6 +1707,8 @@ function createTelegramSenseApp(options) {
|
|
|
1604
1707
|
} : undefined;
|
|
1605
1708
|
const onUpdate = async (update) => {
|
|
1606
1709
|
const callback = update.callback_query;
|
|
1710
|
+
if (callback && rootHostRuntime && await runWithAcceptanceAuditOwner(() => rootHostRuntime.handleUpdate(update)))
|
|
1711
|
+
return true;
|
|
1607
1712
|
if (callback?.data?.startsWith("admit:") && admissionController && callback.message) {
|
|
1608
1713
|
return runWithAcceptanceAuditOwner(async () => {
|
|
1609
1714
|
const actor = await options.admission?.resolveOwner({ botId: botId, userId: String(callback.from.id), chatId: String(callback.message.chat.id), sessionKey: configuredOwnerSessionKey });
|
|
@@ -1637,6 +1742,10 @@ function createTelegramSenseApp(options) {
|
|
|
1637
1742
|
inboxStore,
|
|
1638
1743
|
onMessage,
|
|
1639
1744
|
onUpdate,
|
|
1745
|
+
...(authorityTransport ? {
|
|
1746
|
+
settleTransport: authorityTransport.settleTransport,
|
|
1747
|
+
transportMetadata: authorityTransport.metadataForUpdate,
|
|
1748
|
+
} : {}),
|
|
1640
1749
|
acceptanceEventMeta: (update, distinctAccount) => {
|
|
1641
1750
|
const marker = options.acceptanceMarker ? options.acceptanceMarker() : (0, sanctuary_acceptance_marker_1.readSanctuaryAcceptanceMarker)(options.agentName);
|
|
1642
1751
|
if (!marker)
|
|
@@ -1706,6 +1815,7 @@ function createTelegramSenseApp(options) {
|
|
|
1706
1815
|
(0, runtime_1.emitNervesEvent)({ level: "error", component: "senses", event: "senses.sanctuary_routine_recovery_error", message: "Sanctuary routine action recovery requires inspection", meta: { agentName: options.agentName, subject, category: error instanceof Error ? error.name : "unknown" } });
|
|
1707
1816
|
}
|
|
1708
1817
|
await runWithAcceptanceAuditOwner(async () => { await approvalRuntime?.recover(); });
|
|
1818
|
+
await runWithAcceptanceAuditOwner(async () => { await rootHostRuntime?.recover(); });
|
|
1709
1819
|
await runWithAcceptanceAuditOwner(async () => { await interactiveControl?.start(); });
|
|
1710
1820
|
try {
|
|
1711
1821
|
await runWithAcceptanceAuditOwner(async () => { await approvalTransport?.reconcileExpired(); });
|
|
@@ -1807,7 +1917,7 @@ function loadTelegramSenseCredentials(agentName) {
|
|
|
1807
1917
|
}
|
|
1808
1918
|
return parseTelegramSenseCredentials(runtime.config);
|
|
1809
1919
|
}
|
|
1810
|
-
async function createProductionTelegramRelationshipComposition(agentName, credentials, agentRootOverride) {
|
|
1920
|
+
async function createProductionTelegramRelationshipComposition(agentName, credentials, agentRootOverride, authorityTransport) {
|
|
1811
1921
|
const agentRoot = agentRootOverride ?? (0, identity_1.getAgentRoot)(agentName);
|
|
1812
1922
|
const botId = canonicalTelegramId(credentials.botId ?? telegramBotIdFromToken(credentials.botToken), "bot id");
|
|
1813
1923
|
const ownerUserId = canonicalTelegramId(credentials.authorizedUserId, "authorized user id");
|
|
@@ -1916,6 +2026,7 @@ async function createProductionTelegramRelationshipComposition(agentName, creden
|
|
|
1916
2026
|
const live = await store.get(current.id);
|
|
1917
2027
|
if (!live || !exactTelegramIdentity(live, bindings[0].externalId))
|
|
1918
2028
|
throw new Error("Telegram contact identity changed");
|
|
2029
|
+
await authorityTransport?.revokeChat({ userId: bindings[0].externalId, chatId: bindings[0].externalId });
|
|
1919
2030
|
const { capabilityProfileId: _removedProfile, ...withoutProfile } = live;
|
|
1920
2031
|
await store.put(live.id, { ...withoutProfile, admissionState: "revoked", initiativePolicy: "none", updatedAt: new Date().toISOString() });
|
|
1921
2032
|
(0, tools_awaiting_1.cancelRelationshipFollowUps)(agentRoot, agentName, { friendId: live.id, channel: "telegram", key: sessionKey });
|
|
@@ -2047,18 +2158,53 @@ async function createProductionTelegramRelationshipComposition(agentName, creden
|
|
|
2047
2158
|
},
|
|
2048
2159
|
};
|
|
2049
2160
|
}
|
|
2050
|
-
async function startTelegramSenseApp(agentName) {
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
agentName
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2161
|
+
async function startTelegramSenseApp(agentName, waitForAuthority = false) {
|
|
2162
|
+
let authorityTransport;
|
|
2163
|
+
let credentials;
|
|
2164
|
+
if (agentName === "sanctuary") {
|
|
2165
|
+
const runtime = (0, runtime_credentials_1.readRuntimeCredentialConfig)(agentName);
|
|
2166
|
+
const machine = (0, runtime_credentials_1.readMachineRuntimeCredentialConfig)(agentName);
|
|
2167
|
+
if (!runtime.ok || !machine.ok)
|
|
2168
|
+
throw new Error("Sanctuary Telegram credential inventory is unavailable; migration readback is required");
|
|
2169
|
+
let waiting = false;
|
|
2170
|
+
for (;;) {
|
|
2171
|
+
try {
|
|
2172
|
+
;
|
|
2173
|
+
({ credentials, authorityTransport } = (0, sanctuary_authority_resident_1.openSanctuaryResidentAuthority)(runtime.config, machine.config));
|
|
2174
|
+
break;
|
|
2175
|
+
}
|
|
2176
|
+
catch (error) {
|
|
2177
|
+
if (!waitForAuthority || error?.code !== "ENOENT")
|
|
2178
|
+
throw error;
|
|
2179
|
+
if (!waiting) {
|
|
2180
|
+
waiting = true;
|
|
2181
|
+
(0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.sanctuary_gateway_waiting", message: "Telegram is unavailable while root gateway pins are not yet published", meta: { agentName } });
|
|
2182
|
+
}
|
|
2183
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
else {
|
|
2188
|
+
const loaded = loadTelegramSenseCredentials(agentName);
|
|
2189
|
+
credentials = { ...loaded, botId: telegramBotIdFromToken(loaded.botToken) };
|
|
2190
|
+
}
|
|
2191
|
+
let app;
|
|
2192
|
+
try {
|
|
2193
|
+
app = createTelegramSenseApp({
|
|
2194
|
+
agentName,
|
|
2195
|
+
credentials,
|
|
2196
|
+
authorityTransport,
|
|
2197
|
+
...(await createProductionTelegramRelationshipComposition(agentName, credentials, undefined, authorityTransport)),
|
|
2198
|
+
...(agentName === "sanctuary" ? { privilegedFailsafe: {
|
|
2199
|
+
eventRoot: (0, router_1.getExternalEventRoot)(),
|
|
2200
|
+
verifyProtectiveState: createSabQueueProtectiveStateVerifier(),
|
|
2201
|
+
} } : {}),
|
|
2202
|
+
});
|
|
2203
|
+
}
|
|
2204
|
+
catch (error) {
|
|
2205
|
+
authorityTransport?.api.stop();
|
|
2206
|
+
throw error;
|
|
2207
|
+
}
|
|
2062
2208
|
(0, runtime_1.emitNervesEvent)({
|
|
2063
2209
|
component: "senses",
|
|
2064
2210
|
event: "senses.telegram_app_ready",
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.817",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@ouro.bot/cli",
|
|
9
|
-
"version": "0.1.0-alpha.
|
|
9
|
+
"version": "0.1.0-alpha.817",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|