negotium 0.7.0 → 0.8.0
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/README.md +3 -4
- package/dist/agent-helpers.js +17 -8
- package/dist/agent-helpers.js.map +10 -9
- package/dist/background-bash.js.map +2 -2
- package/dist/browser-runtime.js.map +2 -2
- package/dist/{chunk-9h53kw24.js → chunk-1bfta5qh.js} +2 -2
- package/dist/{chunk-9h53kw24.js.map → chunk-1bfta5qh.js.map} +2 -2
- package/dist/chunk-pp6dvrzq.js.map +2 -2
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +419 -150
- package/dist/main.js.map +19 -18
- package/dist/mcp-factories.js +17 -8
- package/dist/mcp-factories.js.map +10 -9
- package/dist/media.js.map +2 -2
- package/dist/prompts.js.map +2 -2
- package/dist/query-runtime.js +7 -2
- package/dist/query-runtime.js.map +7 -6
- package/dist/registry.js +1 -1
- package/dist/runtime/src/identifiers.ts +28 -0
- package/dist/runtime/src/index.ts +21 -2
- package/dist/runtime/src/node-host.ts +5 -1
- package/dist/runtime/src/query/index.ts +0 -1
- package/dist/runtime/src/query/public-runtime.ts +1 -5
- package/dist/runtime/src/query/room-query-registry.ts +4 -2
- package/dist/runtime/src/query/types.ts +0 -76
- package/dist/runtime/src/runtime/turn-runner.ts +4 -2
- package/dist/runtime/src/storage/api-topics.ts +32 -12
- package/dist/runtime/src/storage/storage-public.ts +4 -39
- package/dist/runtime/src/topics/personal-general.ts +3 -3
- package/dist/runtime/src/topics/update.ts +66 -1
- package/dist/runtime/src/types.ts +0 -11
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js.map +2 -2
- package/dist/storage.js +11 -35
- package/dist/storage.js.map +4 -4
- package/dist/types/packages/core/src/identifiers.d.ts +21 -0
- package/dist/types/packages/core/src/query/public-runtime.d.ts +1 -1
- package/dist/types/packages/core/src/query/room-query-registry.d.ts +2 -1
- package/dist/types/packages/core/src/query/types.d.ts +0 -59
- package/dist/types/packages/core/src/storage/api-topics.d.ts +10 -4
- package/dist/types/packages/core/src/storage/storage-public.d.ts +2 -3
- package/dist/types/packages/core/src/types.d.ts +0 -10
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js.map +2 -2
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -3708,7 +3708,7 @@ var exports_version = {};
|
|
|
3708
3708
|
__export(exports_version, {
|
|
3709
3709
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
3710
3710
|
});
|
|
3711
|
-
var NEGOTIUM_VERSION = "0.
|
|
3711
|
+
var NEGOTIUM_VERSION = "0.8.0";
|
|
3712
3712
|
|
|
3713
3713
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3714
3714
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -7884,6 +7884,7 @@ __export(exports_api_topics, {
|
|
|
7884
7884
|
upsertTopic: () => upsertTopic,
|
|
7885
7885
|
stampUnscopedOtiumTopics: () => stampUnscopedOtiumTopics,
|
|
7886
7886
|
setTopicSurfaces: () => setTopicSurfaces,
|
|
7887
|
+
setTopicSurfaceScope: () => setTopicSurfaceScope,
|
|
7887
7888
|
setTopicSessionId: () => setTopicSessionId,
|
|
7888
7889
|
setSurfaceScopeRequired: () => setSurfaceScopeRequired,
|
|
7889
7890
|
setDefaultSurfaceScope: () => setDefaultSurfaceScope,
|
|
@@ -8412,11 +8413,9 @@ function normalizedTitle(title) {
|
|
|
8412
8413
|
return title.trim().toLowerCase();
|
|
8413
8414
|
}
|
|
8414
8415
|
function surfaceScopeForWrite(t) {
|
|
8415
|
-
if (normalizeTopicSurface(t.surface ?? defaultTopicSurface()) !== "otium")
|
|
8416
|
-
return null;
|
|
8417
8416
|
if (t.surfaceScope !== undefined)
|
|
8418
8417
|
return normalizeSurfaceScope(t.surfaceScope);
|
|
8419
|
-
return defaultSurfaceScope();
|
|
8418
|
+
return normalizeTopicSurface(t.surface ?? defaultTopicSurface()) === "otium" ? defaultSurfaceScope() : null;
|
|
8420
8419
|
}
|
|
8421
8420
|
function upsertTopic(t) {
|
|
8422
8421
|
const normalized = normalizeTopicState({
|
|
@@ -8561,6 +8560,13 @@ function setTopicSurfaces(topicIds, surface) {
|
|
|
8561
8560
|
})();
|
|
8562
8561
|
return changed;
|
|
8563
8562
|
}
|
|
8563
|
+
function setTopicSurfaceScope(topicId, surface, surfaceScope) {
|
|
8564
|
+
const normalizedSurface = normalizeTopicSurface(surface);
|
|
8565
|
+
const normalizedScope = normalizeSurfaceScope(surfaceScope);
|
|
8566
|
+
const result = db.query(`UPDATE api_topics SET surface = ?, surface_scope = ?
|
|
8567
|
+
WHERE id = ? AND (surface IS NOT ? OR surface_scope IS NOT ?)`).run(normalizedSurface, normalizedScope, topicId, normalizedSurface, normalizedScope);
|
|
8568
|
+
return Number(result.changes ?? 0) > 0;
|
|
8569
|
+
}
|
|
8564
8570
|
function getTopicByNameForUser(title, userId, lookupScope) {
|
|
8565
8571
|
const opts = "scope" in lookupScope ? {} : lookupScope;
|
|
8566
8572
|
const trimmed = title.trim();
|
|
@@ -11511,9 +11517,17 @@ var init_manager2 = __esm(async () => {
|
|
|
11511
11517
|
}, 30 * 60 * 1000).unref();
|
|
11512
11518
|
});
|
|
11513
11519
|
|
|
11520
|
+
// ../../packages/core/src/identifiers.ts
|
|
11521
|
+
function asTurnId(value) {
|
|
11522
|
+
return value;
|
|
11523
|
+
}
|
|
11524
|
+
function asTurnSlotKey(value) {
|
|
11525
|
+
return value;
|
|
11526
|
+
}
|
|
11527
|
+
|
|
11514
11528
|
// ../../packages/core/src/query/room-query-registry.ts
|
|
11515
11529
|
function isolatedTurnRoomId(topicId, queryId) {
|
|
11516
|
-
return `${topicId}${ISOLATED_TURN_ROOM_MARKER}${queryId}
|
|
11530
|
+
return asTurnSlotKey(`${topicId}${ISOLATED_TURN_ROOM_MARKER}${queryId}`);
|
|
11517
11531
|
}
|
|
11518
11532
|
function isIsolatedTurnRoomId(roomId) {
|
|
11519
11533
|
return roomId.includes(ISOLATED_TURN_ROOM_MARKER);
|
|
@@ -11642,6 +11656,7 @@ function createRoomQueryRegistry(host) {
|
|
|
11642
11656
|
};
|
|
11643
11657
|
}
|
|
11644
11658
|
var ISOLATED_TURN_ROOM_MARKER = "::isolated-turn::";
|
|
11659
|
+
var init_room_query_registry = () => {};
|
|
11645
11660
|
|
|
11646
11661
|
// ../../packages/core/src/query/types.ts
|
|
11647
11662
|
var AbortReason;
|
|
@@ -11867,7 +11882,9 @@ var roomQueryRegistry, interSessionQueue;
|
|
|
11867
11882
|
var init_active_rooms = __esm(async () => {
|
|
11868
11883
|
init_logger();
|
|
11869
11884
|
await init_runtime_leases();
|
|
11885
|
+
init_room_query_registry();
|
|
11870
11886
|
init_types2();
|
|
11887
|
+
init_room_query_registry();
|
|
11871
11888
|
roomQueryRegistry = createRoomQueryRegistry({
|
|
11872
11889
|
instanceId: RUNTIME_INSTANCE_ID,
|
|
11873
11890
|
internalAbortReason: "internal" /* Internal */,
|
|
@@ -19713,8 +19730,8 @@ function startAiTurn(params) {
|
|
|
19713
19730
|
const askReplySources = params.askReplySources;
|
|
19714
19731
|
const sessionRetried = params._sessionRetried === true;
|
|
19715
19732
|
const emptyResponseRetried = params._emptyResponseRetried === true;
|
|
19716
|
-
const queryId = params._queryId ?? randomUUID17();
|
|
19717
|
-
const roomId = turnConcurrency === "isolated" ? isolatedTurnRoomId(topicId, queryId) : topicId;
|
|
19733
|
+
const queryId = asTurnId(params._queryId ?? randomUUID17());
|
|
19734
|
+
const roomId = turnConcurrency === "isolated" ? isolatedTurnRoomId(topicId, queryId) : asTurnSlotKey(topicId);
|
|
19718
19735
|
const currentRuntimeEpoch = getRuntimeTopicEpoch(topic.id);
|
|
19719
19736
|
const runtimeEpoch = params._runtimeEpoch ?? currentRuntimeEpoch;
|
|
19720
19737
|
if (params._runtimeEpoch !== undefined && params._runtimeEpoch !== currentRuntimeEpoch) {
|
|
@@ -23967,6 +23984,40 @@ var init_inbox = __esm(async () => {
|
|
|
23967
23984
|
});
|
|
23968
23985
|
|
|
23969
23986
|
// ../../packages/core/src/topics/update.ts
|
|
23987
|
+
function updateManagerTopicRuntimeConfig(opts) {
|
|
23988
|
+
const current3 = getTopic(opts.topicId);
|
|
23989
|
+
if (!current3)
|
|
23990
|
+
throw new TopicValidationError("Topic not found");
|
|
23991
|
+
if (current3.kind !== "manager") {
|
|
23992
|
+
throw new TopicValidationError("Runtime config agent updates are manager-only");
|
|
23993
|
+
}
|
|
23994
|
+
if (!isAgentKind(opts.agent))
|
|
23995
|
+
throw new TopicValidationError(`Unknown agent '${opts.agent}'`);
|
|
23996
|
+
const registry = getRegistry(opts.agent);
|
|
23997
|
+
if (opts.config.model && resolveModelForAgent(opts.agent, opts.config.model, registry) !== opts.config.model) {
|
|
23998
|
+
throw new TopicValidationError(`Invalid model for agent ${opts.agent}`);
|
|
23999
|
+
}
|
|
24000
|
+
if (opts.config.effort && !registry.validateEffort(opts.config.effort)) {
|
|
24001
|
+
throw new TopicValidationError(`Invalid effort for agent ${opts.agent}`);
|
|
24002
|
+
}
|
|
24003
|
+
const defaultModel = resolveModelForAgent(opts.agent, opts.config.model ?? (opts.agent === current3.agent ? current3.defaultModel : undefined), registry);
|
|
24004
|
+
const requestedEffort = opts.config.effort ?? (opts.agent === current3.agent ? current3.defaultEffort : undefined);
|
|
24005
|
+
const defaultEffort = requestedEffort && registry.validateEffort(requestedEffort) ? requestedEffort : registry.defaultEffort ?? "medium";
|
|
24006
|
+
db.transaction(() => {
|
|
24007
|
+
setApiTopicAgent(current3.id, opts.agent, {
|
|
24008
|
+
model: defaultModel,
|
|
24009
|
+
effort: defaultEffort
|
|
24010
|
+
});
|
|
24011
|
+
setApiTopicConfig(current3.id, opts.config);
|
|
24012
|
+
})();
|
|
24013
|
+
WsHub.get().broadcastTopicUpdated(current3.id);
|
|
24014
|
+
return getTopic(current3.id) ?? {
|
|
24015
|
+
...current3,
|
|
24016
|
+
agent: opts.agent,
|
|
24017
|
+
defaultModel,
|
|
24018
|
+
defaultEffort
|
|
24019
|
+
};
|
|
24020
|
+
}
|
|
23970
24021
|
function updateTopicSettings(opts) {
|
|
23971
24022
|
const current3 = getTopic(opts.topicId);
|
|
23972
24023
|
if (!current3)
|
|
@@ -24052,6 +24103,7 @@ var init_update = __esm(async () => {
|
|
|
24052
24103
|
init_constants();
|
|
24053
24104
|
await init_api_topic_config();
|
|
24054
24105
|
await init_api_topics();
|
|
24106
|
+
await init_forum_db();
|
|
24055
24107
|
await init_create();
|
|
24056
24108
|
init_types();
|
|
24057
24109
|
TopicUpdateConflictError = class TopicUpdateConflictError extends Error {
|
|
@@ -24077,6 +24129,7 @@ __export(exports_src, {
|
|
|
24077
24129
|
upsertTopic: () => upsertTopic,
|
|
24078
24130
|
updateTopicSettings: () => updateTopicSettings,
|
|
24079
24131
|
updateTopic: () => updateTopic,
|
|
24132
|
+
updateManagerTopicRuntimeConfig: () => updateManagerTopicRuntimeConfig,
|
|
24080
24133
|
unregisterNodeRequestHandler: () => unregisterNodeRequestHandler,
|
|
24081
24134
|
triggerTopicAiTurn: () => triggerTopicAiTurn,
|
|
24082
24135
|
transcribeAudio: () => transcribeAudio,
|
|
@@ -24098,6 +24151,7 @@ __export(exports_src, {
|
|
|
24098
24151
|
startAiTurn: () => startAiTurn,
|
|
24099
24152
|
stampUnscopedOtiumTopics: () => stampUnscopedOtiumTopics,
|
|
24100
24153
|
setTopicSurfaces: () => setTopicSurfaces,
|
|
24154
|
+
setTopicSurfaceScope: () => setTopicSurfaceScope,
|
|
24101
24155
|
setTopicSessionId: () => setTopicSessionId,
|
|
24102
24156
|
setSurfaceScopeRequired: () => setSurfaceScopeRequired,
|
|
24103
24157
|
setRuntimeMcpPort: () => setRuntimeMcpPort,
|
|
@@ -24695,6 +24749,7 @@ __export(exports_node_host, {
|
|
|
24695
24749
|
writeDecisionGraphSvg: () => writeDecisionGraphSvg,
|
|
24696
24750
|
upsertTopic: () => upsertTopic,
|
|
24697
24751
|
updateTopicSettings: () => updateTopicSettings,
|
|
24752
|
+
updateManagerTopicRuntimeConfig: () => updateManagerTopicRuntimeConfig,
|
|
24698
24753
|
updateApiMessageText: () => updateApiMessageText,
|
|
24699
24754
|
topicService: () => topicService,
|
|
24700
24755
|
switchTopicModel: () => switchTopicModel,
|
|
@@ -29370,7 +29425,6 @@ __export(exports_storage_public, {
|
|
|
29370
29425
|
waitForRequiredRuntimeProcessLease: () => waitForRequiredRuntimeProcessLease,
|
|
29371
29426
|
validateDecisionGraph: () => validateDecisionGraph,
|
|
29372
29427
|
upsertTopic: () => upsertTopic,
|
|
29373
|
-
updateTopicThreadId: () => updateTopicThreadId,
|
|
29374
29428
|
updateTasks: () => updateTasks,
|
|
29375
29429
|
updateDecisions: () => updateDecisions,
|
|
29376
29430
|
updateApiMessageUsage: () => updateApiMessageUsage,
|
|
@@ -29392,21 +29446,12 @@ __export(exports_storage_public, {
|
|
|
29392
29446
|
softDeleteApiMessage: () => softDeleteApiMessage,
|
|
29393
29447
|
settleTopicArchiveJob: () => settleTopicArchiveJob,
|
|
29394
29448
|
setTopicSurfaces: () => setTopicSurfaces,
|
|
29449
|
+
setTopicSurfaceScope: () => setTopicSurfaceScope,
|
|
29395
29450
|
setTopicSessionId: () => setTopicSessionId,
|
|
29396
|
-
setTopicMcpExtra: () => setTopicMcpExtra,
|
|
29397
|
-
setTopicMcpEnabled: () => setTopicMcpEnabled,
|
|
29398
|
-
setTopicForkOrigin: () => setTopicForkOrigin,
|
|
29399
|
-
setTopicDescription: () => setTopicDescription,
|
|
29400
29451
|
setTopicBrief: () => setTopicBrief,
|
|
29401
29452
|
setTopicArchiveState: () => setTopicArchiveState,
|
|
29402
|
-
setTopicAgentAndSession: () => setTopicAgentAndSession,
|
|
29403
|
-
setTopicAgentAndClearSession: () => setTopicAgentAndClearSession,
|
|
29404
|
-
setTopicAgent: () => setTopicAgent,
|
|
29405
29453
|
setSurfaceScopeRequired: () => setSurfaceScopeRequired,
|
|
29406
|
-
setSessionForTopic: () => setSessionForTopic,
|
|
29407
|
-
setLastShownConfig: () => setLastShownConfig,
|
|
29408
29454
|
setGlobalAiName: () => setGlobalAiName,
|
|
29409
|
-
setDmSessionId: () => setDmSessionId,
|
|
29410
29455
|
setDefaultSurfaceScope: () => setDefaultSurfaceScope,
|
|
29411
29456
|
setApiTopicConfig: () => setApiTopicConfig,
|
|
29412
29457
|
setApiTopicAgent: () => setApiTopicAgent,
|
|
@@ -29422,8 +29467,6 @@ __export(exports_storage_public, {
|
|
|
29422
29467
|
reparentTopicChildren: () => reparentTopicChildren,
|
|
29423
29468
|
renderTaskList: () => renderTaskList,
|
|
29424
29469
|
renderDecisionList: () => renderDecisionList,
|
|
29425
|
-
renameTopic: () => renameTopic,
|
|
29426
|
-
removeTopic: () => removeTopic,
|
|
29427
29470
|
removeSentFilesForTopic: () => removeSentFilesForTopic,
|
|
29428
29471
|
removeParticipantFromDB: () => removeParticipantFromDB,
|
|
29429
29472
|
removeDeadRuntimeProcessLeases: () => removeDeadRuntimeProcessLeases,
|
|
@@ -29466,49 +29509,34 @@ __export(exports_storage_public, {
|
|
|
29466
29509
|
hasActiveConversation: () => hasActiveConversation,
|
|
29467
29510
|
grantSubagentTellTarget: () => grantSubagentTellTarget,
|
|
29468
29511
|
getWikiDir: () => getWikiDir,
|
|
29469
|
-
getUserConfig: () => getUserConfig,
|
|
29470
29512
|
getTopicStats: () => getTopicStats,
|
|
29471
29513
|
getTopicSessionId: () => getTopicSessionId,
|
|
29472
|
-
getTopicNames: () => getTopicNames,
|
|
29473
29514
|
getTopicMemoryOrigin: () => getTopicMemoryOrigin,
|
|
29474
29515
|
getTopicMemoryFilePaths: () => getTopicMemoryFilePaths,
|
|
29475
|
-
getTopicMcpConfig: () => getTopicMcpConfig,
|
|
29476
|
-
getTopicDescription: () => getTopicDescription,
|
|
29477
29516
|
getTopicByNameForUser: () => getTopicByNameForUser,
|
|
29478
29517
|
getTopicByNameAndKind: () => getTopicByNameAndKind,
|
|
29479
29518
|
getTopicByName: () => getTopicByName,
|
|
29480
29519
|
getTopicBrief: () => getTopicBrief,
|
|
29481
29520
|
getTopicArchiveState: () => getTopicArchiveState,
|
|
29482
|
-
getTopicAgentSwitchState: () => getTopicAgentSwitchState,
|
|
29483
|
-
getTopicAgent: () => getTopicAgent,
|
|
29484
29521
|
getTopic: () => getTopic,
|
|
29485
29522
|
getThreadSummaries: () => getThreadSummaries,
|
|
29486
29523
|
getTaskFilePath: () => getTaskFilePath,
|
|
29487
29524
|
getStats: () => getStats,
|
|
29488
29525
|
getSharedWikiDir: () => getSharedWikiDir,
|
|
29489
|
-
getSessionForTopic: () => getSessionForTopic,
|
|
29490
29526
|
getRuntimeProcessLease: () => getRuntimeProcessLease,
|
|
29491
29527
|
getMessagesForTopicAfterRowid: () => getMessagesForTopicAfterRowid,
|
|
29492
29528
|
getManagerTopicForUser: () => getManagerTopicForUser,
|
|
29493
|
-
getLastShownConfig: () => getLastShownConfig,
|
|
29494
29529
|
getLastMessagePreviews: () => getLastMessagePreviews,
|
|
29495
29530
|
getGlobalAiName: () => getGlobalAiName,
|
|
29496
|
-
getForumTopicByName: () => getTopicByName2,
|
|
29497
|
-
getDmSessionId: () => getDmSessionId,
|
|
29498
29531
|
getDecisionGraphSvgPath: () => getDecisionGraphSvgPath,
|
|
29499
29532
|
getDecisionFilePath: () => getDecisionFilePath,
|
|
29500
29533
|
getConversationPath: () => getConversationPath,
|
|
29501
|
-
getCommunicateThreadId: () => getCommunicateThreadId,
|
|
29502
29534
|
getApiTopicConfig: () => getApiTopicConfig,
|
|
29503
29535
|
getApiMessage: () => getApiMessage,
|
|
29504
|
-
getAllUserIds: () => getAllUserIds,
|
|
29505
|
-
getAllTopics: () => getAllTopics,
|
|
29506
29536
|
getAllMessagesForTopic: () => getAllMessagesForTopic,
|
|
29507
29537
|
getActiveConversationPath: () => getActiveConversationPath,
|
|
29508
29538
|
forum: () => exports_forum,
|
|
29509
29539
|
formatTopicArchiveTranscriptRecord: () => formatTopicArchiveTranscriptRecord,
|
|
29510
|
-
flushSessionCache: () => flushSessionCache,
|
|
29511
|
-
findUserByThread: () => findUserByThread,
|
|
29512
29540
|
findTopicTitleConflict: () => findTopicTitleConflict,
|
|
29513
29541
|
findRecentUserMessage: () => findRecentUserMessage,
|
|
29514
29542
|
findLastSessionIdForAgent: () => findLastSessionIdForAgent,
|
|
@@ -29536,10 +29564,8 @@ __export(exports_storage_public, {
|
|
|
29536
29564
|
configureStorageHost: () => configureStorageHost2,
|
|
29537
29565
|
cloneConversationLog: () => cloneConversationLog,
|
|
29538
29566
|
clearTopicSessionId: () => clearTopicSessionId,
|
|
29539
|
-
clearSessionForTopic: () => clearSessionForTopic,
|
|
29540
29567
|
clearPendingAskSources: () => clearPendingAskSources,
|
|
29541
29568
|
clearPendingAsk: () => clearPendingAsk,
|
|
29542
|
-
clearDmSessionId: () => clearDmSessionId,
|
|
29543
29569
|
claimTopicArchiveJob: () => claimTopicArchiveJob,
|
|
29544
29570
|
claimAskUserGateAndSelect: () => claimAskUserGateAndSelect,
|
|
29545
29571
|
captureMessageSnapshotForTopic: () => captureMessageSnapshotForTopic,
|
|
@@ -29559,7 +29585,6 @@ __export(exports_storage_public, {
|
|
|
29559
29585
|
apiMessages: () => exports_api_messages,
|
|
29560
29586
|
anonymizeApiMessages: () => anonymizeApiMessages,
|
|
29561
29587
|
aiMentionFromMode: () => aiMentionFromMode,
|
|
29562
|
-
addTopic: () => addTopic,
|
|
29563
29588
|
addParticipantToDB: () => addParticipantToDB,
|
|
29564
29589
|
activityLog: () => exports_activity_log,
|
|
29565
29590
|
acquireRuntimeProcessLease: () => acquireRuntimeProcessLease,
|
|
@@ -29591,7 +29616,6 @@ var init_storage_public = __esm(async () => {
|
|
|
29591
29616
|
await init_decisions();
|
|
29592
29617
|
init_decisions();
|
|
29593
29618
|
await init_forum();
|
|
29594
|
-
await init_forum();
|
|
29595
29619
|
await init_runtime_process_leases();
|
|
29596
29620
|
init_runtime_process_leases();
|
|
29597
29621
|
await init_session_asks();
|
|
@@ -29606,7 +29630,6 @@ var init_storage_public = __esm(async () => {
|
|
|
29606
29630
|
await init_topic_archive_state();
|
|
29607
29631
|
init_topic_archive_state();
|
|
29608
29632
|
await init_topic_settings();
|
|
29609
|
-
init_topic_settings();
|
|
29610
29633
|
await init_wiki();
|
|
29611
29634
|
init_wiki();
|
|
29612
29635
|
init_wiki_summary_names();
|
|
@@ -34005,6 +34028,16 @@ function createNodeControlHandler(options) {
|
|
|
34005
34028
|
const topic = getTopic(topicId);
|
|
34006
34029
|
if (!topic || !topicInRequestScope(req, topic))
|
|
34007
34030
|
return jsonError(404, "Topic not found");
|
|
34031
|
+
let requestedAgent;
|
|
34032
|
+
if ("agent" in body) {
|
|
34033
|
+
if (topic.kind !== "manager") {
|
|
34034
|
+
return jsonError(400, "Config endpoint agent updates are manager-only");
|
|
34035
|
+
}
|
|
34036
|
+
if (typeof body.agent !== "string" || !["claude", "codex", "maestro"].includes(body.agent)) {
|
|
34037
|
+
return jsonError(400, "Invalid agent");
|
|
34038
|
+
}
|
|
34039
|
+
requestedAgent = body.agent;
|
|
34040
|
+
}
|
|
34008
34041
|
const next = { ...getApiTopicConfig(topicId) ?? {} };
|
|
34009
34042
|
for (const key of ["model", "effort"]) {
|
|
34010
34043
|
if (!(key in body))
|
|
@@ -34039,11 +34072,26 @@ function createNodeControlHandler(options) {
|
|
|
34039
34072
|
else
|
|
34040
34073
|
return jsonError(400, `${key} must be a boolean or null`);
|
|
34041
34074
|
}
|
|
34042
|
-
|
|
34075
|
+
let updatedTopic = topic;
|
|
34076
|
+
try {
|
|
34077
|
+
if (requestedAgent) {
|
|
34078
|
+
updatedTopic = updateManagerTopicRuntimeConfig({
|
|
34079
|
+
topicId,
|
|
34080
|
+
agent: requestedAgent,
|
|
34081
|
+
config: next
|
|
34082
|
+
});
|
|
34083
|
+
} else {
|
|
34084
|
+
setApiTopicConfig(topicId, next);
|
|
34085
|
+
}
|
|
34086
|
+
} catch (err2) {
|
|
34087
|
+
if (err2 instanceof TopicValidationError)
|
|
34088
|
+
return jsonError(400, err2.message);
|
|
34089
|
+
throw err2;
|
|
34090
|
+
}
|
|
34043
34091
|
return Response.json({
|
|
34044
34092
|
ok: true,
|
|
34045
34093
|
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
34046
|
-
topic,
|
|
34094
|
+
topic: updatedTopic,
|
|
34047
34095
|
config: getApiTopicConfig(topicId) ?? {}
|
|
34048
34096
|
});
|
|
34049
34097
|
}
|
|
@@ -42657,12 +42705,15 @@ var init_telegram_api = __esm(() => {
|
|
|
42657
42705
|
});
|
|
42658
42706
|
|
|
42659
42707
|
// ../../adapters/telegram/src/commands.ts
|
|
42660
|
-
function resolveTelegramTopicArg(argument, userId) {
|
|
42661
|
-
const byName = getTopicByNameForUser(argument, userId, {
|
|
42708
|
+
function resolveTelegramTopicArg(argument, userId, surfaceScope) {
|
|
42709
|
+
const byName = getTopicByNameForUser(argument, userId, {
|
|
42710
|
+
surface: "telegram",
|
|
42711
|
+
surfaceScope
|
|
42712
|
+
});
|
|
42662
42713
|
if (byName)
|
|
42663
42714
|
return byName;
|
|
42664
42715
|
const byId = getTopic(argument);
|
|
42665
|
-
return byId?.surface === "telegram" ? byId : null;
|
|
42716
|
+
return byId?.surface === "telegram" && (byId.surfaceScope ?? null) === surfaceScope ? byId : null;
|
|
42666
42717
|
}
|
|
42667
42718
|
function createTelegramCommandRouter(context) {
|
|
42668
42719
|
const { userId, reply, currentTopicId, bindMapping, loadTopic, unloadTopic, abortTurn } = context;
|
|
@@ -42700,7 +42751,7 @@ function createTelegramCommandRouter(context) {
|
|
|
42700
42751
|
return;
|
|
42701
42752
|
}
|
|
42702
42753
|
try {
|
|
42703
|
-
const topic = context.getOrCreateTopic(`${context.titleFor(chatId, threadId)}-${argument}`, argument);
|
|
42754
|
+
const topic = context.getOrCreateTopic(chatId, `${context.titleFor(chatId, threadId)}-${argument}`, argument);
|
|
42704
42755
|
bindMapping(chatId, threadId, topic.id);
|
|
42705
42756
|
reply(chatId, threadId, `agent set to ${argument} \u2014 topic "${topic.title}"`);
|
|
42706
42757
|
} catch (err2) {
|
|
@@ -42709,7 +42760,10 @@ function createTelegramCommandRouter(context) {
|
|
|
42709
42760
|
return;
|
|
42710
42761
|
}
|
|
42711
42762
|
case "/topics": {
|
|
42712
|
-
const topics = listTopics({
|
|
42763
|
+
const topics = listTopics({
|
|
42764
|
+
surface: "telegram",
|
|
42765
|
+
surfaceScope: context.surfaceScopeFor(chatId)
|
|
42766
|
+
}).filter((topic) => isTopicVisible(topic) && topic.participants.some((person) => person.userId === userId));
|
|
42713
42767
|
reply(chatId, threadId, topics.length ? topics.map((topic) => `- ${topic.title}${topic.agent ? ` (${topic.agent})` : ""}`).join(`
|
|
42714
42768
|
`) : "no topics");
|
|
42715
42769
|
return;
|
|
@@ -42740,9 +42794,10 @@ function createTelegramCommandRouter(context) {
|
|
|
42740
42794
|
userId,
|
|
42741
42795
|
kind: "agent",
|
|
42742
42796
|
surface: "telegram",
|
|
42797
|
+
surfaceScope: context.surfaceScopeFor(chatId),
|
|
42743
42798
|
...context.defaultAgent ? { agent: context.defaultAgent } : {}
|
|
42744
42799
|
};
|
|
42745
|
-
const fromForumGeneral = context.
|
|
42800
|
+
const fromForumGeneral = context.isForumGeneral(chatId, threadId);
|
|
42746
42801
|
const topic = fromForumGeneral ? topicService.create(createOptions) : context.registerTopic(createOptions);
|
|
42747
42802
|
if (fromForumGeneral) {
|
|
42748
42803
|
reply(chatId, threadId, `creating new topic "${topic.title}"`);
|
|
@@ -42760,7 +42815,7 @@ function createTelegramCommandRouter(context) {
|
|
|
42760
42815
|
reply(chatId, threadId, "usage: /load <topic>");
|
|
42761
42816
|
return;
|
|
42762
42817
|
}
|
|
42763
|
-
const candidate = resolveTelegramTopicArg(argument, userId);
|
|
42818
|
+
const candidate = resolveTelegramTopicArg(argument, userId, context.surfaceScopeFor(chatId));
|
|
42764
42819
|
const topic = candidate && isTopicVisible(candidate) ? candidate : null;
|
|
42765
42820
|
if (!topic || !loadTopic(chatId, topic.id, threadId)) {
|
|
42766
42821
|
reply(chatId, threadId, `no visible topic matching "${argument}"`);
|
|
@@ -42805,7 +42860,7 @@ function createTelegramCommandRouter(context) {
|
|
|
42805
42860
|
case "/del!": {
|
|
42806
42861
|
const force = command === "/del!";
|
|
42807
42862
|
const topicId = currentTopicId(chatId, threadId);
|
|
42808
|
-
const topic = argument ? resolveTelegramTopicArg(argument, userId) : topicId ? getTopic(topicId) : null;
|
|
42863
|
+
const topic = argument ? resolveTelegramTopicArg(argument, userId, context.surfaceScopeFor(chatId)) : topicId ? getTopic(topicId) : null;
|
|
42809
42864
|
if (!topic) {
|
|
42810
42865
|
reply(chatId, threadId, argument ? `no topic named "${argument}"` : "this chat has no topic \u2014 usage: /del [name]");
|
|
42811
42866
|
return;
|
|
@@ -42890,6 +42945,12 @@ function createTables(db4) {
|
|
|
42890
42945
|
key TEXT PRIMARY KEY,
|
|
42891
42946
|
value TEXT NOT NULL
|
|
42892
42947
|
)`);
|
|
42948
|
+
db4.run(`CREATE TABLE IF NOT EXISTS telegram_groups (
|
|
42949
|
+
chat_id INTEGER PRIMARY KEY,
|
|
42950
|
+
title TEXT,
|
|
42951
|
+
owner_telegram_user_id INTEGER,
|
|
42952
|
+
created_at TEXT NOT NULL
|
|
42953
|
+
)`);
|
|
42893
42954
|
db4.run(`CREATE TABLE IF NOT EXISTS runtime_inbox (
|
|
42894
42955
|
seq INTEGER PRIMARY KEY,
|
|
42895
42956
|
runtime_message_id TEXT,
|
|
@@ -42919,6 +42980,14 @@ function openMappingStore(path) {
|
|
|
42919
42980
|
const db4 = new Database2(dbPath);
|
|
42920
42981
|
migrateLegacySchema(db4);
|
|
42921
42982
|
createTables(db4);
|
|
42983
|
+
const legacyForum = db4.query("SELECT value FROM settings WHERE key = 'forum_chat_id'").get();
|
|
42984
|
+
if (legacyForum) {
|
|
42985
|
+
const chatId = Number.parseInt(legacyForum.value, 10);
|
|
42986
|
+
if (Number.isSafeInteger(chatId)) {
|
|
42987
|
+
db4.run(`INSERT OR IGNORE INTO telegram_groups (chat_id, created_at)
|
|
42988
|
+
VALUES (?, ?)`, [chatId, new Date().toISOString()]);
|
|
42989
|
+
}
|
|
42990
|
+
}
|
|
42922
42991
|
migrateOutboxSchema(db4);
|
|
42923
42992
|
migrateRuntimeInboxSchema(db4);
|
|
42924
42993
|
return {
|
|
@@ -42971,6 +43040,32 @@ function openMappingStore(path) {
|
|
|
42971
43040
|
clearForumChatId() {
|
|
42972
43041
|
db4.run("DELETE FROM settings WHERE key = 'forum_chat_id'");
|
|
42973
43042
|
},
|
|
43043
|
+
loadGroups() {
|
|
43044
|
+
const rows = db4.query("SELECT chat_id, title, owner_telegram_user_id FROM telegram_groups ORDER BY created_at").all();
|
|
43045
|
+
return rows.map((row) => ({
|
|
43046
|
+
chatId: row.chat_id,
|
|
43047
|
+
...row.title ? { title: row.title } : {},
|
|
43048
|
+
...row.owner_telegram_user_id !== null ? { ownerTelegramUserId: row.owner_telegram_user_id } : {}
|
|
43049
|
+
}));
|
|
43050
|
+
},
|
|
43051
|
+
saveGroup(group) {
|
|
43052
|
+
db4.run(`INSERT INTO telegram_groups (chat_id, title, owner_telegram_user_id, created_at)
|
|
43053
|
+
VALUES (?, ?, ?, ?)
|
|
43054
|
+
ON CONFLICT(chat_id) DO UPDATE SET
|
|
43055
|
+
title = COALESCE(excluded.title, telegram_groups.title),
|
|
43056
|
+
owner_telegram_user_id = COALESCE(
|
|
43057
|
+
excluded.owner_telegram_user_id,
|
|
43058
|
+
telegram_groups.owner_telegram_user_id
|
|
43059
|
+
)`, [
|
|
43060
|
+
group.chatId,
|
|
43061
|
+
group.title ?? null,
|
|
43062
|
+
group.ownerTelegramUserId ?? null,
|
|
43063
|
+
new Date().toISOString()
|
|
43064
|
+
]);
|
|
43065
|
+
},
|
|
43066
|
+
deleteGroup(chatId) {
|
|
43067
|
+
db4.run("DELETE FROM telegram_groups WHERE chat_id = ?", [chatId]);
|
|
43068
|
+
},
|
|
42974
43069
|
isFlagSet(key) {
|
|
42975
43070
|
return db4.query("SELECT 1 FROM settings WHERE key = ?").get(key) !== null;
|
|
42976
43071
|
},
|
|
@@ -43310,6 +43405,15 @@ function renderOutbound(text2, maxLen = 4096) {
|
|
|
43310
43405
|
// ../../adapters/telegram/src/adapter.ts
|
|
43311
43406
|
import { existsSync as existsSync37 } from "fs";
|
|
43312
43407
|
import { basename as basename13, extname as extname6 } from "path";
|
|
43408
|
+
function telegramGroupScope(chatId) {
|
|
43409
|
+
return `tg:${chatId}`;
|
|
43410
|
+
}
|
|
43411
|
+
function telegramGroupIdFromScope(scope) {
|
|
43412
|
+
if (!scope?.startsWith("tg:"))
|
|
43413
|
+
return null;
|
|
43414
|
+
const chatId = Number(scope.slice(3));
|
|
43415
|
+
return Number.isSafeInteger(chatId) ? chatId : null;
|
|
43416
|
+
}
|
|
43313
43417
|
function startTelegramAdapter(opts) {
|
|
43314
43418
|
const { client, forumChatId } = opts;
|
|
43315
43419
|
const userId = opts.userId ?? "local";
|
|
@@ -43328,16 +43432,42 @@ function startTelegramAdapter(opts) {
|
|
|
43328
43432
|
const dispatchTurn = opts.startTurn ?? startAiTurn;
|
|
43329
43433
|
const store = openMappingStore(opts.mappingDbPath);
|
|
43330
43434
|
const restoredForumChatId = store.loadForumChatId();
|
|
43331
|
-
|
|
43332
|
-
|
|
43333
|
-
let forumMode = initialForumChatId !== undefined && typeof client.createForumTopic === "function";
|
|
43334
|
-
let forumManageTopicsAvailable = forumMode && forumChatId !== undefined;
|
|
43335
|
-
if (forumChatId !== undefined)
|
|
43435
|
+
if (forumChatId !== undefined) {
|
|
43436
|
+
store.saveGroup({ chatId: forumChatId });
|
|
43336
43437
|
store.saveForumChatId(forumChatId);
|
|
43337
|
-
|
|
43338
|
-
|
|
43438
|
+
}
|
|
43439
|
+
const forumGroups = new Map;
|
|
43440
|
+
for (const group of store.loadGroups()) {
|
|
43441
|
+
forumGroups.set(group.chatId, {
|
|
43442
|
+
chatId: group.chatId,
|
|
43443
|
+
manageTopicsAvailable: group.chatId === forumChatId,
|
|
43444
|
+
configured: group.chatId === forumChatId,
|
|
43445
|
+
permissionRevision: 0
|
|
43446
|
+
});
|
|
43447
|
+
}
|
|
43448
|
+
if (restoredForumChatId !== undefined && !forumGroups.has(restoredForumChatId)) {
|
|
43449
|
+
forumGroups.set(restoredForumChatId, {
|
|
43450
|
+
chatId: restoredForumChatId,
|
|
43451
|
+
manageTopicsAvailable: false,
|
|
43452
|
+
configured: false,
|
|
43453
|
+
permissionRevision: 0
|
|
43454
|
+
});
|
|
43455
|
+
}
|
|
43456
|
+
if (forumGroups.size > 0 && typeof client.createForumTopic !== "function") {
|
|
43457
|
+
logger.warn({ forumChatIds: [...forumGroups.keys()] }, "telegram adapter: forum groups configured but client lacks createForumTopic");
|
|
43339
43458
|
}
|
|
43340
43459
|
const personalGeneral = ensurePersonalGeneral(userId, "telegram");
|
|
43460
|
+
const groupGenerals = new Map;
|
|
43461
|
+
const generalForGroup = (chatId) => {
|
|
43462
|
+
const existing = groupGenerals.get(chatId);
|
|
43463
|
+
if (existing)
|
|
43464
|
+
return existing;
|
|
43465
|
+
const general = ensurePersonalGeneral(userId, "telegram", {
|
|
43466
|
+
surfaceScope: telegramGroupScope(chatId)
|
|
43467
|
+
});
|
|
43468
|
+
groupGenerals.set(chatId, general);
|
|
43469
|
+
return general;
|
|
43470
|
+
};
|
|
43341
43471
|
const byKey = new Map;
|
|
43342
43472
|
const byTopic = new Map;
|
|
43343
43473
|
const targetByQueryId = new Map;
|
|
@@ -43511,6 +43641,22 @@ function startTelegramAdapter(opts) {
|
|
|
43511
43641
|
}
|
|
43512
43642
|
function bindMapping(chatId, threadId, topicId, { persist = true } = {}) {
|
|
43513
43643
|
const key = mappingKey(chatId, threadId);
|
|
43644
|
+
if (forumGroups.has(chatId)) {
|
|
43645
|
+
const topic = getTopic(topicId);
|
|
43646
|
+
const expectedScope = telegramGroupScope(chatId);
|
|
43647
|
+
if (!topic || topic.surface !== "telegram" || (topic.surfaceScope ?? null) !== expectedScope) {
|
|
43648
|
+
throw new Error(`refusing to bind Telegram group ${chatId} to topic ${topicId} outside ${expectedScope}`);
|
|
43649
|
+
}
|
|
43650
|
+
for (const existing of [...byTopic.get(topicId) ?? []]) {
|
|
43651
|
+
if (existing.chatId !== chatId || mappingKey(existing.chatId, existing.threadId) === key) {
|
|
43652
|
+
continue;
|
|
43653
|
+
}
|
|
43654
|
+
detachFromTopic(existing);
|
|
43655
|
+
byKey.delete(mappingKey(existing.chatId, existing.threadId));
|
|
43656
|
+
if (persist)
|
|
43657
|
+
store.deleteByChat(existing.chatId, existing.threadId);
|
|
43658
|
+
}
|
|
43659
|
+
}
|
|
43514
43660
|
const prev = byKey.get(key);
|
|
43515
43661
|
if (prev) {
|
|
43516
43662
|
if (prev.topicId === topicId)
|
|
@@ -43577,7 +43723,8 @@ function startTelegramAdapter(opts) {
|
|
|
43577
43723
|
}
|
|
43578
43724
|
function loadExistingTopic(chatId, topicId, threadId) {
|
|
43579
43725
|
const topic = getTopic(topicId);
|
|
43580
|
-
|
|
43726
|
+
const expectedScope = forumGroups.has(chatId) ? telegramGroupScope(chatId) : null;
|
|
43727
|
+
if (!topic?.participants.some((participant) => participant.userId === userId) || topic.surface !== "telegram" || (topic.surfaceScope ?? null) !== expectedScope) {
|
|
43581
43728
|
return false;
|
|
43582
43729
|
}
|
|
43583
43730
|
bindMapping(chatId, threadId, topic.id);
|
|
@@ -43585,7 +43732,10 @@ function startTelegramAdapter(opts) {
|
|
|
43585
43732
|
}
|
|
43586
43733
|
if (!store.isFlagSet(SURFACE_BACKFILL_FLAG)) {
|
|
43587
43734
|
const mappedIds = [
|
|
43588
|
-
...new Set(store.load().
|
|
43735
|
+
...new Set(store.load().flatMap((mapping) => {
|
|
43736
|
+
const topic = getTopic(mapping.topicId);
|
|
43737
|
+
return topic && topic.kind !== "manager" && topic.participants.some((participant) => participant.userId === userId) ? [topic.id] : [];
|
|
43738
|
+
}))
|
|
43589
43739
|
];
|
|
43590
43740
|
const moved = setTopicSurfaces(mappedIds, "telegram");
|
|
43591
43741
|
store.setFlag(SURFACE_BACKFILL_FLAG);
|
|
@@ -43593,12 +43743,70 @@ function startTelegramAdapter(opts) {
|
|
|
43593
43743
|
logger.info({ moved, mapped: mappedIds.length }, "telegram adapter: moved mapped topics onto the telegram surface");
|
|
43594
43744
|
}
|
|
43595
43745
|
}
|
|
43746
|
+
if (!store.isFlagSet(GROUP_SCOPE_BACKFILL_FLAG)) {
|
|
43747
|
+
const groupIds = new Set(forumGroups.keys());
|
|
43748
|
+
const groupsByTopic = new Map;
|
|
43749
|
+
for (const mapping of store.load()) {
|
|
43750
|
+
if (!groupIds.has(mapping.chatId))
|
|
43751
|
+
continue;
|
|
43752
|
+
const groups = groupsByTopic.get(mapping.topicId) ?? new Set;
|
|
43753
|
+
groups.add(mapping.chatId);
|
|
43754
|
+
groupsByTopic.set(mapping.topicId, groups);
|
|
43755
|
+
}
|
|
43756
|
+
let filed = 0;
|
|
43757
|
+
for (const [topicId, groups] of groupsByTopic) {
|
|
43758
|
+
if (groups.size !== 1) {
|
|
43759
|
+
logger.warn({ topicId, groupIds: [...groups] }, "telegram adapter: legacy topic spans multiple groups; scope migration skipped");
|
|
43760
|
+
continue;
|
|
43761
|
+
}
|
|
43762
|
+
const topic = getTopic(topicId);
|
|
43763
|
+
if (!topic || topic.kind === "manager" || topic.surface !== "telegram" || !topic.participants.some((participant) => participant.userId === userId)) {
|
|
43764
|
+
continue;
|
|
43765
|
+
}
|
|
43766
|
+
const [chatId] = groups;
|
|
43767
|
+
if (chatId !== undefined) {
|
|
43768
|
+
const targetScope = telegramGroupScope(chatId);
|
|
43769
|
+
const currentScope = topic.surfaceScope ?? null;
|
|
43770
|
+
if (currentScope !== null && currentScope !== targetScope) {
|
|
43771
|
+
logger.warn({ topicId, currentScope, targetScope }, "telegram adapter: legacy mapping conflicts with an existing topic namespace");
|
|
43772
|
+
continue;
|
|
43773
|
+
}
|
|
43774
|
+
const titleConflict = findTopicTitleConflict(topic.title, topic.kind ?? "agent", {
|
|
43775
|
+
excludeTopicId: topic.id,
|
|
43776
|
+
surface: "telegram",
|
|
43777
|
+
surfaceScope: targetScope
|
|
43778
|
+
});
|
|
43779
|
+
if (titleConflict) {
|
|
43780
|
+
logger.warn({ topicId, conflictTopicId: titleConflict.id, targetScope }, "telegram adapter: legacy topic title conflicts in target namespace");
|
|
43781
|
+
continue;
|
|
43782
|
+
}
|
|
43783
|
+
filed += Number(setTopicSurfaceScope(topicId, "telegram", targetScope));
|
|
43784
|
+
}
|
|
43785
|
+
}
|
|
43786
|
+
store.setFlag(GROUP_SCOPE_BACKFILL_FLAG);
|
|
43787
|
+
if (filed > 0) {
|
|
43788
|
+
logger.info({ filed }, "telegram adapter: filed legacy topics into group namespaces");
|
|
43789
|
+
}
|
|
43790
|
+
}
|
|
43596
43791
|
for (const persisted of store.load()) {
|
|
43597
43792
|
const topic = getTopic(persisted.topicId);
|
|
43598
|
-
|
|
43793
|
+
const expectedScope = forumGroups.has(persisted.chatId) ? telegramGroupScope(persisted.chatId) : null;
|
|
43794
|
+
if (topic?.participants.some((participant) => participant.userId === userId) && topic.surface === "telegram" && (topic.surfaceScope ?? null) === expectedScope) {
|
|
43599
43795
|
bindMapping(persisted.chatId, persisted.threadId, persisted.topicId, { persist: false });
|
|
43600
43796
|
continue;
|
|
43601
43797
|
}
|
|
43798
|
+
if (topic) {
|
|
43799
|
+
store.deleteByChat(persisted.chatId, persisted.threadId);
|
|
43800
|
+
logger.warn({
|
|
43801
|
+
chatId: persisted.chatId,
|
|
43802
|
+
threadId: persisted.threadId,
|
|
43803
|
+
topicId: persisted.topicId,
|
|
43804
|
+
topicSurface: topic.surface,
|
|
43805
|
+
topicSurfaceScope: topic.surfaceScope ?? null,
|
|
43806
|
+
expectedScope
|
|
43807
|
+
}, "telegram adapter: quarantined mapping outside its topic namespace");
|
|
43808
|
+
continue;
|
|
43809
|
+
}
|
|
43602
43810
|
cleanupPersistedMapping(persisted, "telegram adapter: stale forum thread cleanup failed");
|
|
43603
43811
|
}
|
|
43604
43812
|
function reconcileStaleMappings() {
|
|
@@ -43618,8 +43826,15 @@ function startTelegramAdapter(opts) {
|
|
|
43618
43826
|
suppressMaterialize--;
|
|
43619
43827
|
}
|
|
43620
43828
|
}
|
|
43621
|
-
function getOrCreateTopic(title, agent) {
|
|
43622
|
-
|
|
43829
|
+
function getOrCreateTopic(chatId, title, agent) {
|
|
43830
|
+
const surfaceScope = forumGroups.has(chatId) ? telegramGroupScope(chatId) : null;
|
|
43831
|
+
return getTopicByNameForUser(title, userId, { surface: "telegram", surfaceScope }) ?? registerTopicLocal({
|
|
43832
|
+
title,
|
|
43833
|
+
userId,
|
|
43834
|
+
kind: "agent",
|
|
43835
|
+
surfaceScope,
|
|
43836
|
+
...agent ? { agent } : {}
|
|
43837
|
+
});
|
|
43623
43838
|
}
|
|
43624
43839
|
function resolveMapping(chatId, threadId) {
|
|
43625
43840
|
const cached = byKey.get(mappingKey(chatId, threadId));
|
|
@@ -43629,7 +43844,7 @@ function startTelegramAdapter(opts) {
|
|
|
43629
43844
|
return topic2;
|
|
43630
43845
|
unbindTopic(cached.topicId);
|
|
43631
43846
|
}
|
|
43632
|
-
const topic = getOrCreateTopic(titleFor(chatId, threadId), opts.defaultAgent);
|
|
43847
|
+
const topic = getOrCreateTopic(chatId, titleFor(chatId, threadId), opts.defaultAgent);
|
|
43633
43848
|
bindMapping(chatId, threadId, topic.id);
|
|
43634
43849
|
return topic;
|
|
43635
43850
|
}
|
|
@@ -43947,12 +44162,16 @@ function startTelegramAdapter(opts) {
|
|
|
43947
44162
|
const pendingByTopic = new Map;
|
|
43948
44163
|
const permissionBlockedTopics = new Map;
|
|
43949
44164
|
const materializeTombstones = new Map;
|
|
43950
|
-
if (
|
|
44165
|
+
if (forumGroups.size > 0) {
|
|
43951
44166
|
for (const t of store.loadTombstones())
|
|
43952
44167
|
materializeTombstones.set(t.topicId, t.title);
|
|
43953
44168
|
}
|
|
43954
44169
|
function deliverFallback(topicId, title, payload) {
|
|
43955
|
-
|
|
44170
|
+
const topic = getTopic(topicId);
|
|
44171
|
+
const chatId = telegramGroupIdFromScope(topic?.surfaceScope);
|
|
44172
|
+
if (chatId === null)
|
|
44173
|
+
return Promise.resolve();
|
|
44174
|
+
return deliverToTargets(topicId, [{ chatId, topicId }], {
|
|
43956
44175
|
text: payload.text ? `[${title}] ${payload.text}` : "",
|
|
43957
44176
|
files: payload.files,
|
|
43958
44177
|
runtimeMessageId: payload.runtimeMessageId,
|
|
@@ -43965,16 +44184,18 @@ function startTelegramAdapter(opts) {
|
|
|
43965
44184
|
}
|
|
43966
44185
|
}
|
|
43967
44186
|
function materializeTopic(topic) {
|
|
43968
|
-
if (
|
|
44187
|
+
if (topic.surface !== "telegram" || !topic.participants?.some((participant) => participant.userId === userId)) {
|
|
43969
44188
|
return false;
|
|
43970
44189
|
}
|
|
43971
|
-
|
|
44190
|
+
const materializationChat = telegramGroupIdFromScope(topic.surfaceScope);
|
|
44191
|
+
if (materializationChat === null)
|
|
43972
44192
|
return false;
|
|
43973
|
-
|
|
44193
|
+
const group = forumGroups.get(materializationChat);
|
|
44194
|
+
if (!group?.manageTopicsAvailable || suppressMaterialize > 0 || byTopic.has(topic.id) || pendingByTopic.has(topic.id) || permissionBlockedTopics.has(topic.id) || materializeTombstones.has(topic.id)) {
|
|
43974
44195
|
return false;
|
|
43975
|
-
|
|
44196
|
+
}
|
|
44197
|
+
if (!isTopicVisible(topic))
|
|
43976
44198
|
return false;
|
|
43977
|
-
const materializationChat = forumChat;
|
|
43978
44199
|
const pending2 = { buffer: [], cancelled: false };
|
|
43979
44200
|
pendingByTopic.set(topic.id, pending2);
|
|
43980
44201
|
(async () => {
|
|
@@ -43988,12 +44209,12 @@ function startTelegramAdapter(opts) {
|
|
|
43988
44209
|
return;
|
|
43989
44210
|
const errorInfo = telegramErrorInfo(err2);
|
|
43990
44211
|
if (isManageTopicsPermissionError(errorInfo)) {
|
|
43991
|
-
const permissionWasAvailable =
|
|
43992
|
-
|
|
44212
|
+
const permissionWasAvailable = group.manageTopicsAvailable;
|
|
44213
|
+
group.manageTopicsAvailable = false;
|
|
43993
44214
|
permissionBlockedTopics.set(topic.id, topic.title);
|
|
43994
44215
|
logger.warn({ err: err2, topicId: topic.id, title: topic.title }, "telegram adapter: Manage Topics unavailable \u2014 waiting for permission recovery");
|
|
43995
44216
|
if (permissionWasAvailable) {
|
|
43996
|
-
reply(
|
|
44217
|
+
reply(materializationChat, undefined, 'Forum topic creation is paused. Enable the bot administrator permission "Manage Topics"; pending topics will be retried automatically.');
|
|
43997
44218
|
}
|
|
43998
44219
|
flushBuffered(topic.id, pending2.buffer, (payload) => deliverFallback(topic.id, topic.title, payload));
|
|
43999
44220
|
return;
|
|
@@ -44082,8 +44303,10 @@ function startTelegramAdapter(opts) {
|
|
|
44082
44303
|
const topic = getTopic(topicId);
|
|
44083
44304
|
if (!topic)
|
|
44084
44305
|
return false;
|
|
44085
|
-
|
|
44086
|
-
|
|
44306
|
+
const groupId = telegramGroupIdFromScope(topic.surfaceScope);
|
|
44307
|
+
const group = groupId === null ? undefined : forumGroups.get(groupId);
|
|
44308
|
+
if (group) {
|
|
44309
|
+
if (!group.manageTopicsAvailable || permissionBlockedTopics.has(topicId)) {
|
|
44087
44310
|
enqueueSend(topicId, () => deliverFallback(topicId, topic.title, payload)).then(payload.onSettled);
|
|
44088
44311
|
return true;
|
|
44089
44312
|
}
|
|
@@ -44229,32 +44452,52 @@ ${suffix}`;
|
|
|
44229
44452
|
return;
|
|
44230
44453
|
await client.sendMessage(chatId, onboardingGuide(bot?.username), threadOpts(threadId)).catch((err2) => logger.warn({ err: err2, chatId }, "telegram adapter: onboarding guide failed"));
|
|
44231
44454
|
}
|
|
44232
|
-
function materializeVisibleTopics() {
|
|
44233
|
-
|
|
44455
|
+
function materializeVisibleTopics(chatId) {
|
|
44456
|
+
const group = forumGroups.get(chatId);
|
|
44457
|
+
if (!group?.manageTopicsAvailable)
|
|
44234
44458
|
return;
|
|
44235
|
-
|
|
44459
|
+
const topics = listTopics({
|
|
44460
|
+
surface: "telegram",
|
|
44461
|
+
surfaceScope: telegramGroupScope(chatId)
|
|
44462
|
+
});
|
|
44463
|
+
for (const topic of topics) {
|
|
44464
|
+
if (topic.kind === "manager")
|
|
44465
|
+
continue;
|
|
44236
44466
|
if (isTopicVisible(topic) && topic.participants.some((participant) => participant.userId === userId)) {
|
|
44237
44467
|
materializeTopic(topic);
|
|
44238
44468
|
}
|
|
44239
44469
|
}
|
|
44240
44470
|
}
|
|
44241
|
-
function restoreForumTopicCreation({ retryPermanent = false } = {}) {
|
|
44242
|
-
|
|
44243
|
-
|
|
44471
|
+
function restoreForumTopicCreation(chatId, { retryPermanent = false } = {}) {
|
|
44472
|
+
const group = forumGroups.get(chatId);
|
|
44473
|
+
if (!group)
|
|
44474
|
+
return;
|
|
44475
|
+
group.manageTopicsAvailable = true;
|
|
44476
|
+
for (const topicId of [...permissionBlockedTopics.keys()]) {
|
|
44477
|
+
if (telegramGroupIdFromScope(getTopic(topicId)?.surfaceScope) === chatId) {
|
|
44478
|
+
permissionBlockedTopics.delete(topicId);
|
|
44479
|
+
}
|
|
44480
|
+
}
|
|
44244
44481
|
if (retryPermanent) {
|
|
44245
|
-
materializeTombstones.
|
|
44246
|
-
|
|
44482
|
+
for (const topicId of [...materializeTombstones.keys()]) {
|
|
44483
|
+
if (telegramGroupIdFromScope(getTopic(topicId)?.surfaceScope) === chatId) {
|
|
44484
|
+
materializeTombstones.delete(topicId);
|
|
44485
|
+
store.deleteTombstone(topicId);
|
|
44486
|
+
}
|
|
44487
|
+
}
|
|
44247
44488
|
}
|
|
44248
44489
|
reconcileStaleMappings();
|
|
44249
|
-
materializeVisibleTopics();
|
|
44490
|
+
materializeVisibleTopics(chatId);
|
|
44250
44491
|
}
|
|
44251
44492
|
async function notifyOwnerDms(text2) {
|
|
44252
44493
|
await Promise.allSettled([...ownerDmChatIds].map((chatId) => client.sendMessage(chatId, text2)));
|
|
44253
44494
|
}
|
|
44254
44495
|
async function disconnectForum(chatId) {
|
|
44255
|
-
if (!
|
|
44496
|
+
if (!forumGroups.has(chatId))
|
|
44256
44497
|
return false;
|
|
44257
44498
|
for (const [topicId, pending2] of pendingByTopic) {
|
|
44499
|
+
if (telegramGroupIdFromScope(getTopic(topicId)?.surfaceScope) !== chatId)
|
|
44500
|
+
continue;
|
|
44258
44501
|
pending2.cancelled = true;
|
|
44259
44502
|
if (pendingByTopic.get(topicId) === pending2)
|
|
44260
44503
|
pendingByTopic.delete(topicId);
|
|
@@ -44267,14 +44510,23 @@ ${suffix}`;
|
|
|
44267
44510
|
if (target.chatId === chatId)
|
|
44268
44511
|
targetByQueryId.delete(queryId);
|
|
44269
44512
|
}
|
|
44270
|
-
permissionBlockedTopics.
|
|
44271
|
-
|
|
44272
|
-
|
|
44513
|
+
for (const topicId of [...permissionBlockedTopics.keys()]) {
|
|
44514
|
+
if (telegramGroupIdFromScope(getTopic(topicId)?.surfaceScope) === chatId) {
|
|
44515
|
+
permissionBlockedTopics.delete(topicId);
|
|
44516
|
+
}
|
|
44517
|
+
}
|
|
44518
|
+
for (const topicId of [...materializeTombstones.keys()]) {
|
|
44519
|
+
if (telegramGroupIdFromScope(getTopic(topicId)?.surfaceScope) === chatId) {
|
|
44520
|
+
materializeTombstones.delete(topicId);
|
|
44521
|
+
store.deleteTombstone(topicId);
|
|
44522
|
+
}
|
|
44523
|
+
}
|
|
44273
44524
|
store.outboxDeleteByChat(chatId);
|
|
44274
|
-
store.
|
|
44275
|
-
|
|
44276
|
-
|
|
44277
|
-
|
|
44525
|
+
store.deleteGroup(chatId);
|
|
44526
|
+
if (store.loadForumChatId() === chatId)
|
|
44527
|
+
store.clearForumChatId();
|
|
44528
|
+
forumGroups.delete(chatId);
|
|
44529
|
+
groupGenerals.delete(chatId);
|
|
44278
44530
|
await notifyOwnerDms("The Telegram forum was disconnected because the bot left or was removed. Your Negotium topics were preserved; promote the bot in a forum group to reconnect.");
|
|
44279
44531
|
logger.info({ userId, forumChatId: chatId }, "telegram adapter: forum disconnected");
|
|
44280
44532
|
return true;
|
|
@@ -44284,16 +44536,14 @@ ${suffix}`;
|
|
|
44284
44536
|
reply(ownerTelegramId, undefined, "This Telegram client cannot create forum topics, so the group was not connected.");
|
|
44285
44537
|
return false;
|
|
44286
44538
|
}
|
|
44287
|
-
if (forumMode && forumChat !== chat.id) {
|
|
44288
|
-
reply(ownerTelegramId, undefined, `A different forum group (${forumChat}) is already connected to this Negotium node.`);
|
|
44289
|
-
return false;
|
|
44290
|
-
}
|
|
44291
44539
|
const hasManageTopics = canManageTopics(botMember);
|
|
44292
|
-
|
|
44293
|
-
|
|
44294
|
-
|
|
44540
|
+
const existingGroup = forumGroups.get(chat.id);
|
|
44541
|
+
if (existingGroup) {
|
|
44542
|
+
existingGroup.permissionRevision += 1;
|
|
44543
|
+
const recovered = hasManageTopics && !existingGroup.manageTopicsAvailable;
|
|
44544
|
+
const lostPermission = !hasManageTopics && existingGroup.manageTopicsAvailable;
|
|
44295
44545
|
if (hasManageTopics) {
|
|
44296
|
-
restoreForumTopicCreation({ retryPermanent: recovered });
|
|
44546
|
+
restoreForumTopicCreation(chat.id, { retryPermanent: recovered });
|
|
44297
44547
|
if (recovered) {
|
|
44298
44548
|
await Promise.allSettled([
|
|
44299
44549
|
client.sendMessage(chat.id, "Manage Topics permission confirmed. Pending Negotium topics are being created now."),
|
|
@@ -44301,23 +44551,29 @@ ${suffix}`;
|
|
|
44301
44551
|
]);
|
|
44302
44552
|
}
|
|
44303
44553
|
} else {
|
|
44304
|
-
|
|
44554
|
+
existingGroup.manageTopicsAvailable = false;
|
|
44305
44555
|
if (lostPermission) {
|
|
44306
44556
|
await notifyOwnerDms(`Manage Topics permission was removed from \u201C${chat.title?.trim() || chat.id}\u201D. Existing topics are preserved; restore the permission to resume topic creation.`);
|
|
44307
44557
|
}
|
|
44308
44558
|
}
|
|
44309
44559
|
return true;
|
|
44310
44560
|
}
|
|
44311
|
-
|
|
44312
|
-
|
|
44313
|
-
|
|
44314
|
-
|
|
44315
|
-
|
|
44316
|
-
|
|
44317
|
-
store.
|
|
44318
|
-
|
|
44561
|
+
forumGroups.set(chat.id, {
|
|
44562
|
+
chatId: chat.id,
|
|
44563
|
+
manageTopicsAvailable: hasManageTopics,
|
|
44564
|
+
configured: chat.id === forumChatId,
|
|
44565
|
+
permissionRevision: 1
|
|
44566
|
+
});
|
|
44567
|
+
store.saveGroup({
|
|
44568
|
+
chatId: chat.id,
|
|
44569
|
+
title: chat.title?.trim(),
|
|
44570
|
+
ownerTelegramUserId: ownerTelegramId
|
|
44571
|
+
});
|
|
44572
|
+
if (store.loadForumChatId() === undefined)
|
|
44573
|
+
store.saveForumChatId(chat.id);
|
|
44574
|
+
bindMapping(chat.id, undefined, generalForGroup(chat.id).id);
|
|
44319
44575
|
ownerDmChatIds.add(ownerTelegramId);
|
|
44320
|
-
materializeVisibleTopics();
|
|
44576
|
+
materializeVisibleTopics(chat.id);
|
|
44321
44577
|
const title = chat.title?.trim() || String(chat.id);
|
|
44322
44578
|
const permissionWarning = hasManageTopics ? "" : `
|
|
44323
44579
|
|
|
@@ -44339,9 +44595,8 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44339
44595
|
if (msg.chat.type !== "supergroup" || !msg.chat.is_forum || senderId === undefined || !isAllowed(senderId)) {
|
|
44340
44596
|
return false;
|
|
44341
44597
|
}
|
|
44342
|
-
|
|
44343
|
-
|
|
44344
|
-
if (forumMode && forumManageTopicsAvailable)
|
|
44598
|
+
const connected = forumGroups.get(msg.chat.id);
|
|
44599
|
+
if (connected?.manageTopicsAvailable)
|
|
44345
44600
|
return true;
|
|
44346
44601
|
if (typeof client.getMe !== "function" || typeof client.getChatMember !== "function") {
|
|
44347
44602
|
return false;
|
|
@@ -44357,38 +44612,49 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44357
44612
|
if (!isChatAdmin(botMember) || !isChatAdmin(senderMember))
|
|
44358
44613
|
return false;
|
|
44359
44614
|
await linkForumAndAnnounce(senderId, msg.chat, botMember);
|
|
44360
|
-
return
|
|
44615
|
+
return forumGroups.has(msg.chat.id);
|
|
44361
44616
|
} catch (err2) {
|
|
44362
44617
|
logger.debug({ err: err2, groupId: msg.chat.id, senderId }, "telegram adapter: lazy forum auto-connect check failed");
|
|
44363
44618
|
return false;
|
|
44364
44619
|
}
|
|
44365
44620
|
}
|
|
44366
44621
|
async function verifyInitialForumPermissions() {
|
|
44367
|
-
|
|
44368
|
-
|
|
44369
|
-
if (forumChatId !== undefined)
|
|
44622
|
+
const initialGroups = [...forumGroups.values()];
|
|
44623
|
+
if (initialGroups.length === 0)
|
|
44370
44624
|
return;
|
|
44371
44625
|
if (typeof client.getMe !== "function" || typeof client.getChatMember !== "function") {
|
|
44372
|
-
|
|
44626
|
+
for (const group of initialGroups) {
|
|
44627
|
+
if (forumGroups.get(group.chatId) === group)
|
|
44628
|
+
group.manageTopicsAvailable = true;
|
|
44629
|
+
}
|
|
44373
44630
|
return;
|
|
44374
44631
|
}
|
|
44375
|
-
|
|
44376
|
-
|
|
44377
|
-
|
|
44378
|
-
|
|
44379
|
-
|
|
44380
|
-
|
|
44381
|
-
|
|
44382
|
-
|
|
44383
|
-
|
|
44384
|
-
|
|
44385
|
-
const
|
|
44386
|
-
|
|
44387
|
-
|
|
44388
|
-
|
|
44632
|
+
const bot = await resolveBotIdentity();
|
|
44633
|
+
if (!bot || stopped)
|
|
44634
|
+
return;
|
|
44635
|
+
for (const group of initialGroups) {
|
|
44636
|
+
if (forumGroups.get(group.chatId) !== group)
|
|
44637
|
+
continue;
|
|
44638
|
+
if (group.configured)
|
|
44639
|
+
continue;
|
|
44640
|
+
try {
|
|
44641
|
+
const permissionRevision = group.permissionRevision;
|
|
44642
|
+
const member = await client.getChatMember(group.chatId, bot.id);
|
|
44643
|
+
if (forumGroups.get(group.chatId) !== group || group.permissionRevision !== permissionRevision) {
|
|
44644
|
+
continue;
|
|
44645
|
+
}
|
|
44646
|
+
if (member.status === "left" || member.status === "kicked") {
|
|
44647
|
+
await disconnectForum(group.chatId);
|
|
44648
|
+
continue;
|
|
44649
|
+
}
|
|
44650
|
+
if (canManageTopics(member)) {
|
|
44651
|
+
restoreForumTopicCreation(group.chatId, { retryPermanent: !group.configured });
|
|
44652
|
+
} else {
|
|
44653
|
+
group.manageTopicsAvailable = false;
|
|
44654
|
+
}
|
|
44655
|
+
} catch (err2) {
|
|
44656
|
+
logger.warn({ err: err2, forumChatId: group.chatId }, "telegram adapter: initial forum permission check failed");
|
|
44389
44657
|
}
|
|
44390
|
-
} catch (err2) {
|
|
44391
|
-
logger.warn({ err: err2, forumChatId: forumChat }, "telegram adapter: initial forum permission check failed");
|
|
44392
44658
|
}
|
|
44393
44659
|
}
|
|
44394
44660
|
verifyInitialForumPermissions();
|
|
@@ -44440,7 +44706,8 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44440
44706
|
const handleCommand = createTelegramCommandRouter({
|
|
44441
44707
|
userId,
|
|
44442
44708
|
defaultAgent: opts.defaultAgent,
|
|
44443
|
-
|
|
44709
|
+
surfaceScopeFor: (chatId) => forumGroups.has(chatId) ? telegramGroupScope(chatId) : null,
|
|
44710
|
+
isForumGeneral: (chatId, threadId) => forumGroups.has(chatId) && threadId === undefined,
|
|
44444
44711
|
resolveBotUsername: async () => (await resolveBotIdentity())?.username,
|
|
44445
44712
|
isVaultOwner,
|
|
44446
44713
|
reply,
|
|
@@ -44466,8 +44733,10 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44466
44733
|
const firstPrivateContact = privateDm && !byKey.has(mappingKey(chatId));
|
|
44467
44734
|
if (privateDm)
|
|
44468
44735
|
ownerDmChatIds.add(chatId);
|
|
44469
|
-
if (privateDm
|
|
44736
|
+
if (privateDm) {
|
|
44470
44737
|
bindMapping(chatId, threadId, personalGeneral.id);
|
|
44738
|
+
} else if (forumGroups.has(chatId) && threadId === undefined) {
|
|
44739
|
+
bindMapping(chatId, threadId, generalForGroup(chatId).id);
|
|
44471
44740
|
}
|
|
44472
44741
|
if (firstPrivateContact && text2 !== "/start") {
|
|
44473
44742
|
sendOnboardingGuide(chatId);
|
|
@@ -44499,9 +44768,7 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44499
44768
|
if (!isAllowed(msg.from?.id))
|
|
44500
44769
|
return;
|
|
44501
44770
|
if (msg.chat.type === "supergroup" && msg.chat.is_forum) {
|
|
44502
|
-
if (
|
|
44503
|
-
return;
|
|
44504
|
-
if (!forumMode || !forumManageTopicsAvailable) {
|
|
44771
|
+
if (!forumGroups.get(msg.chat.id)?.manageTopicsAvailable) {
|
|
44505
44772
|
tryAutoConnectFromMessage(msg).then((connected) => {
|
|
44506
44773
|
if (connected && !stopped)
|
|
44507
44774
|
handleIncomingMessage(msg);
|
|
@@ -44515,19 +44782,21 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44515
44782
|
if (stopped || update.chat.type !== "supergroup" || !update.chat.is_forum)
|
|
44516
44783
|
return;
|
|
44517
44784
|
const status = update.new_chat_member?.status;
|
|
44518
|
-
if ((status === "left" || status === "kicked") &&
|
|
44785
|
+
if ((status === "left" || status === "kicked") && forumGroups.has(update.chat.id)) {
|
|
44519
44786
|
disconnectForum(update.chat.id).catch((err2) => logger.warn({ err: err2, groupId: update.chat.id }, "telegram adapter: forum disconnect failed"));
|
|
44520
44787
|
return;
|
|
44521
44788
|
}
|
|
44522
|
-
if (
|
|
44523
|
-
const
|
|
44524
|
-
|
|
44789
|
+
if (forumGroups.has(update.chat.id) && status !== "administrator" && status !== "creator") {
|
|
44790
|
+
const group = forumGroups.get(update.chat.id);
|
|
44791
|
+
group.permissionRevision += 1;
|
|
44792
|
+
const permissionWasAvailable = group.manageTopicsAvailable;
|
|
44793
|
+
group.manageTopicsAvailable = false;
|
|
44525
44794
|
if (permissionWasAvailable) {
|
|
44526
44795
|
notifyOwnerDms('The bot no longer has forum administrator access. Existing topics are preserved; restore administrator + "Manage Topics" to resume topic creation.');
|
|
44527
44796
|
}
|
|
44528
44797
|
return;
|
|
44529
44798
|
}
|
|
44530
|
-
if (status !== "administrator" && status !== "creator" || update.from?.id === undefined || !isAllowed(update.from.id) && (
|
|
44799
|
+
if (status !== "administrator" && status !== "creator" || update.from?.id === undefined || !isAllowed(update.from.id) && !forumGroups.has(update.chat.id)) {
|
|
44531
44800
|
return;
|
|
44532
44801
|
}
|
|
44533
44802
|
linkForumAndAnnounce(update.from.id, update.chat, update.new_chat_member).catch((err2) => logger.warn({ err: err2, groupId: update.chat.id }, "telegram adapter: forum auto-connect failed"));
|
|
@@ -44642,7 +44911,7 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44642
44911
|
const unsubscribe = runtimeBus().subscribe((event) => {
|
|
44643
44912
|
if (stopped)
|
|
44644
44913
|
return;
|
|
44645
|
-
if (event.type === "topic-created"
|
|
44914
|
+
if (event.type === "topic-created") {
|
|
44646
44915
|
materializeTopic(event.payload);
|
|
44647
44916
|
return;
|
|
44648
44917
|
}
|
|
@@ -44693,9 +44962,9 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44693
44962
|
pollRuntimeEvents();
|
|
44694
44963
|
const runtimeEventPollTimer = setInterval(pollRuntimeEvents, 100);
|
|
44695
44964
|
runtimeEventPollTimer.unref?.();
|
|
44696
|
-
|
|
44697
|
-
bindMapping(
|
|
44698
|
-
materializeVisibleTopics();
|
|
44965
|
+
for (const group of forumGroups.values()) {
|
|
44966
|
+
bindMapping(group.chatId, undefined, generalForGroup(group.chatId).id);
|
|
44967
|
+
materializeVisibleTopics(group.chatId);
|
|
44699
44968
|
}
|
|
44700
44969
|
return {
|
|
44701
44970
|
name: "telegram",
|
|
@@ -44718,7 +44987,7 @@ Warning: enable the bot administrator permission "Manage Topics" before creating
|
|
|
44718
44987
|
}
|
|
44719
44988
|
};
|
|
44720
44989
|
}
|
|
44721
|
-
var SURFACE_BACKFILL_FLAG = "surface_backfill_20260808", FORUM_TOPIC_NAME_MAX = 128, MAX_PARENT_HOPS = 5, DEFAULT_SEND_TIMEOUT_MS = 60000, PHOTO_EXTS;
|
|
44990
|
+
var SURFACE_BACKFILL_FLAG = "surface_backfill_20260808", GROUP_SCOPE_BACKFILL_FLAG = "telegram_group_scope_backfill_20260829", FORUM_TOPIC_NAME_MAX = 128, MAX_PARENT_HOPS = 5, DEFAULT_SEND_TIMEOUT_MS = 60000, PHOTO_EXTS;
|
|
44722
44991
|
var init_adapter = __esm(async () => {
|
|
44723
44992
|
await init_src();
|
|
44724
44993
|
await init_commands2();
|
|
@@ -49681,4 +49950,4 @@ switch (command) {
|
|
|
49681
49950
|
}
|
|
49682
49951
|
}
|
|
49683
49952
|
|
|
49684
|
-
//# debugId=
|
|
49953
|
+
//# debugId=37C7DCC041D0DB9F64756E2164756E21
|