@ouro.bot/cli 0.1.0-alpha.816 → 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 +10 -0
- package/deploy/unraid/Dockerfile +6 -0
- package/deploy/unraid/README.txt +280 -60
- 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/core.js +2 -1
- package/dist/heart/daemon/container-spec-auditor-main.js +8 -7
- package/dist/heart/daemon/container-spec-auditor.js +16 -9
- 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/repertoire/tools-sanctuary-host.js +202 -0
- package/dist/repertoire/tools.js +15 -6
- 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/telegram-admission.js +7 -0
- 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 +168 -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;
|
|
@@ -959,6 +991,40 @@ function createTelegramSenseApp(options) {
|
|
|
959
991
|
},
|
|
960
992
|
}) : undefined);
|
|
961
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
|
+
}
|
|
962
1028
|
interactiveControl = useSanctuaryRuntime && approvalTransport
|
|
963
1029
|
? (options._createInteractiveControl ?? sanctuary_interactive_control_1.createSanctuaryInteractiveControl)({
|
|
964
1030
|
agentRoot,
|
|
@@ -1020,7 +1086,10 @@ function createTelegramSenseApp(options) {
|
|
|
1020
1086
|
approvalReconcileTimer = setTimeout(() => {
|
|
1021
1087
|
approvalReconcileTimer = undefined;
|
|
1022
1088
|
scheduleApprovalReconcile();
|
|
1023
|
-
const reconciliation = runWithAcceptanceAuditOwner(
|
|
1089
|
+
const reconciliation = runWithAcceptanceAuditOwner(async () => {
|
|
1090
|
+
await approvalTransport.reconcileExpired();
|
|
1091
|
+
await rootHostRuntime?.recover();
|
|
1092
|
+
}).catch((error) => {
|
|
1024
1093
|
acceptanceAuditBarrier();
|
|
1025
1094
|
(0, runtime_1.emitNervesEvent)({
|
|
1026
1095
|
level: "error",
|
|
@@ -1185,10 +1254,20 @@ function createTelegramSenseApp(options) {
|
|
|
1185
1254
|
},
|
|
1186
1255
|
validateTerminalAnswer: (answer) => contracts.map((contract) => contract.validateTerminalAnswer?.(answer)).find((rejection) => rejection !== undefined),
|
|
1187
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
|
+
}
|
|
1188
1267
|
return {
|
|
1189
1268
|
...runAgentOptions,
|
|
1190
1269
|
...(requiredToolCalls ? { requiredToolCalls } : {}),
|
|
1191
|
-
toolContext:
|
|
1270
|
+
toolContext: currentToolContext,
|
|
1192
1271
|
};
|
|
1193
1272
|
};
|
|
1194
1273
|
};
|
|
@@ -1278,6 +1357,15 @@ function createTelegramSenseApp(options) {
|
|
|
1278
1357
|
},
|
|
1279
1358
|
claimFriend: options.admission.claimFriend,
|
|
1280
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
|
+
} : {}),
|
|
1281
1369
|
commitApprovedIngress: async (input) => {
|
|
1282
1370
|
const sessionKey = `telegram:${input.botId}:${input.userId}`;
|
|
1283
1371
|
const reference = `telegram-admission:${input.admissionId}`;
|
|
@@ -1338,8 +1426,9 @@ function createTelegramSenseApp(options) {
|
|
|
1338
1426
|
const ingested = await (0, telegram_attachments_1.ingestTelegramAttachments)({
|
|
1339
1427
|
agentName: options.agentName,
|
|
1340
1428
|
agentRoot,
|
|
1341
|
-
botToken,
|
|
1429
|
+
...(botToken ? { botToken } : {}),
|
|
1342
1430
|
api,
|
|
1431
|
+
...(authorityTransport ? { downloadFile: authorityTransport.downloadFile } : {}),
|
|
1343
1432
|
...(options.attachmentFetch ? { fetch: options.attachmentFetch } : {}),
|
|
1344
1433
|
attachments: message.attachments ?? [],
|
|
1345
1434
|
});
|
|
@@ -1459,10 +1548,11 @@ function createTelegramSenseApp(options) {
|
|
|
1459
1548
|
chatId: message.chatId,
|
|
1460
1549
|
sessionKey: currentSessionKey,
|
|
1461
1550
|
userMessage: message.text,
|
|
1551
|
+
authority: message.authority,
|
|
1462
1552
|
fullVisibilityProgress: fullVisibility.progress,
|
|
1463
1553
|
}),
|
|
1464
1554
|
} : {}),
|
|
1465
|
-
...(approvalRuntime ? { approvalCoordinatorFactory: approvalRuntime.coordinator } : {}),
|
|
1555
|
+
...(approvalRuntime ? { approvalCoordinatorFactory: rootHostRuntime ? approvalCoordinatorFactory : approvalRuntime.coordinator } : {}),
|
|
1466
1556
|
}), toolReceiptObserver);
|
|
1467
1557
|
const result = collected.result;
|
|
1468
1558
|
let responseFallbackArtifactId;
|
|
@@ -1517,9 +1607,9 @@ function createTelegramSenseApp(options) {
|
|
|
1517
1607
|
...lifecycleCoordinates,
|
|
1518
1608
|
...(acceptanceMarker ? {
|
|
1519
1609
|
outcome: "error",
|
|
1520
|
-
errorDigest: auditDigest("error", redactTelegramPrivateValues(error, [
|
|
1610
|
+
errorDigest: auditDigest("error", redactTelegramPrivateValues(error, [...transportPrivateValues, String(message.updateId), message.messageId])),
|
|
1521
1611
|
deliveryCount: deliveredMessageIds.length,
|
|
1522
|
-
} : { error: redactTelegramPrivateValues(error, [
|
|
1612
|
+
} : { error: redactTelegramPrivateValues(error, [...transportPrivateValues, String(message.updateId), message.messageId]) }),
|
|
1523
1613
|
}, Math.max(Date.now(), lifecycleStartedAt + 1)),
|
|
1524
1614
|
});
|
|
1525
1615
|
const fallback = "I couldn't complete that turn. The failure was recorded; please try again.";
|
|
@@ -1533,7 +1623,7 @@ function createTelegramSenseApp(options) {
|
|
|
1533
1623
|
const grounded = groundedAcceptance;
|
|
1534
1624
|
const schemaVersion = grounded ? "sanctuary-telegram-turn-receipt-v4" : "sanctuary-telegram-turn-receipt-v3";
|
|
1535
1625
|
const hmac = (purpose, value) => sanctuaryTelegramTurnReceiptDigest(identityKey, schemaVersion, purpose, value);
|
|
1536
|
-
const redact = (value) => [
|
|
1626
|
+
const redact = (value) => [...transportPrivateValues, String(message.updateId), message.messageId]
|
|
1537
1627
|
.reduce((text, privateValue) => privateValue.length >= 5 ? text.replaceAll(privateValue, "[REDACTED]") : text, value);
|
|
1538
1628
|
const deliveries = deliveredMessageIds.map((messageId, index) => {
|
|
1539
1629
|
const chunk = deliveredChunks[index];
|
|
@@ -1592,6 +1682,13 @@ function createTelegramSenseApp(options) {
|
|
|
1592
1682
|
await admissionController.handleUnknown(message);
|
|
1593
1683
|
return;
|
|
1594
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
|
+
});
|
|
1595
1692
|
const hydrated = await hydrateAuthorizedMessage({
|
|
1596
1693
|
updateId: message.updateId,
|
|
1597
1694
|
messageId: String(message.messageId),
|
|
@@ -1610,6 +1707,8 @@ function createTelegramSenseApp(options) {
|
|
|
1610
1707
|
} : undefined;
|
|
1611
1708
|
const onUpdate = async (update) => {
|
|
1612
1709
|
const callback = update.callback_query;
|
|
1710
|
+
if (callback && rootHostRuntime && await runWithAcceptanceAuditOwner(() => rootHostRuntime.handleUpdate(update)))
|
|
1711
|
+
return true;
|
|
1613
1712
|
if (callback?.data?.startsWith("admit:") && admissionController && callback.message) {
|
|
1614
1713
|
return runWithAcceptanceAuditOwner(async () => {
|
|
1615
1714
|
const actor = await options.admission?.resolveOwner({ botId: botId, userId: String(callback.from.id), chatId: String(callback.message.chat.id), sessionKey: configuredOwnerSessionKey });
|
|
@@ -1643,6 +1742,10 @@ function createTelegramSenseApp(options) {
|
|
|
1643
1742
|
inboxStore,
|
|
1644
1743
|
onMessage,
|
|
1645
1744
|
onUpdate,
|
|
1745
|
+
...(authorityTransport ? {
|
|
1746
|
+
settleTransport: authorityTransport.settleTransport,
|
|
1747
|
+
transportMetadata: authorityTransport.metadataForUpdate,
|
|
1748
|
+
} : {}),
|
|
1646
1749
|
acceptanceEventMeta: (update, distinctAccount) => {
|
|
1647
1750
|
const marker = options.acceptanceMarker ? options.acceptanceMarker() : (0, sanctuary_acceptance_marker_1.readSanctuaryAcceptanceMarker)(options.agentName);
|
|
1648
1751
|
if (!marker)
|
|
@@ -1712,6 +1815,7 @@ function createTelegramSenseApp(options) {
|
|
|
1712
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" } });
|
|
1713
1816
|
}
|
|
1714
1817
|
await runWithAcceptanceAuditOwner(async () => { await approvalRuntime?.recover(); });
|
|
1818
|
+
await runWithAcceptanceAuditOwner(async () => { await rootHostRuntime?.recover(); });
|
|
1715
1819
|
await runWithAcceptanceAuditOwner(async () => { await interactiveControl?.start(); });
|
|
1716
1820
|
try {
|
|
1717
1821
|
await runWithAcceptanceAuditOwner(async () => { await approvalTransport?.reconcileExpired(); });
|
|
@@ -1813,7 +1917,7 @@ function loadTelegramSenseCredentials(agentName) {
|
|
|
1813
1917
|
}
|
|
1814
1918
|
return parseTelegramSenseCredentials(runtime.config);
|
|
1815
1919
|
}
|
|
1816
|
-
async function createProductionTelegramRelationshipComposition(agentName, credentials, agentRootOverride) {
|
|
1920
|
+
async function createProductionTelegramRelationshipComposition(agentName, credentials, agentRootOverride, authorityTransport) {
|
|
1817
1921
|
const agentRoot = agentRootOverride ?? (0, identity_1.getAgentRoot)(agentName);
|
|
1818
1922
|
const botId = canonicalTelegramId(credentials.botId ?? telegramBotIdFromToken(credentials.botToken), "bot id");
|
|
1819
1923
|
const ownerUserId = canonicalTelegramId(credentials.authorizedUserId, "authorized user id");
|
|
@@ -1922,6 +2026,7 @@ async function createProductionTelegramRelationshipComposition(agentName, creden
|
|
|
1922
2026
|
const live = await store.get(current.id);
|
|
1923
2027
|
if (!live || !exactTelegramIdentity(live, bindings[0].externalId))
|
|
1924
2028
|
throw new Error("Telegram contact identity changed");
|
|
2029
|
+
await authorityTransport?.revokeChat({ userId: bindings[0].externalId, chatId: bindings[0].externalId });
|
|
1925
2030
|
const { capabilityProfileId: _removedProfile, ...withoutProfile } = live;
|
|
1926
2031
|
await store.put(live.id, { ...withoutProfile, admissionState: "revoked", initiativePolicy: "none", updatedAt: new Date().toISOString() });
|
|
1927
2032
|
(0, tools_awaiting_1.cancelRelationshipFollowUps)(agentRoot, agentName, { friendId: live.id, channel: "telegram", key: sessionKey });
|
|
@@ -2053,18 +2158,53 @@ async function createProductionTelegramRelationshipComposition(agentName, creden
|
|
|
2053
2158
|
},
|
|
2054
2159
|
};
|
|
2055
2160
|
}
|
|
2056
|
-
async function startTelegramSenseApp(agentName) {
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
agentName
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
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
|
+
}
|
|
2068
2208
|
(0, runtime_1.emitNervesEvent)({
|
|
2069
2209
|
component: "senses",
|
|
2070
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",
|