@senguoyun/dsh-arkme 0.1.26 → 0.1.28
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/lib/client.js +4573 -2619
- package/lib/client.js.map +1 -1
- package/lib/index.js +35 -1
- package/lib/persistent-extension.js +1 -1
- package/lib/{persistent-runtime-BqJb5fuJ.js → persistent-runtime-CaPUsLwg.js} +377 -17
- package/lib/types/arkme-service.d.ts +36 -1
- package/lib/types/arkme-service.d.ts.map +1 -1
- package/lib/types/client/ArkmeBotConversationSurface.d.ts +7 -0
- package/lib/types/client/ArkmeBotConversationSurface.d.ts.map +1 -0
- package/lib/types/client/ArkmeBotCreateDialog.d.ts +2 -0
- package/lib/types/client/ArkmeBotCreateDialog.d.ts.map +1 -1
- package/lib/types/client/ArkmeBotSettingsPanel.d.ts +8 -0
- package/lib/types/client/ArkmeBotSettingsPanel.d.ts.map +1 -0
- package/lib/types/client/ArkmePersistentShell.d.ts +1 -1
- package/lib/types/client/ArkmePersistentShell.d.ts.map +1 -1
- package/lib/types/client/ArkmeProductNavigation.d.ts +2 -1
- package/lib/types/client/ArkmeProductNavigation.d.ts.map +1 -1
- package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
- package/lib/types/client/ArkmeVirtualWorkspace.d.ts +6 -2
- package/lib/types/client/ArkmeVirtualWorkspace.d.ts.map +1 -1
- package/lib/types/client/api.d.ts +1 -1
- package/lib/types/client/api.d.ts.map +1 -1
- package/lib/types/client/bot-directory-preferences.d.ts +15 -0
- package/lib/types/client/bot-directory-preferences.d.ts.map +1 -0
- package/lib/types/client/ui-controller.d.ts +4 -2
- package/lib/types/client/ui-controller.d.ts.map +1 -1
- package/lib/types/host-api.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/services/bot-service.d.ts +41 -1
- package/lib/types/services/bot-service.d.ts.map +1 -1
- package/lib/types/services/source-service.d.ts +15 -1
- package/lib/types/services/source-service.d.ts.map +1 -1
- package/lib/types/types.d.ts +63 -1
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as securePrivateDirectory, c as securePrivateFileSync, i as prepareProfilePackageManager, n as isArkmeProfilePackageName, o as securePrivateDirectorySync, r as localExtensionPnpmArgs, s as securePrivateFile, t as applyArkmeProfileBundlePolicy } from "./profile-bundle-policy-CvojZuTD.js";
|
|
2
|
-
import { A as readNativeBundleTarballV3, B as ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE, C as arkmeSandboxEntryId, D as inspectNativeBundleArtifactV3, E as inspectBundleArtifact, F as unpackArkmeExtension, H as validateVoiceprintPcm16Wav, I as ARKME_EXTENSION_FORMAT, J as ARKME_WORLD_PUBLISH_MAX_IMAGES, M as assertExtensionArtifactSize, N as canonicalExtensionJson, O as packBundleFiles, P as sha256Hex, Q as ArkmeOutgoingCallError, S as ArkmeBundleArtifactError, T as canonicalBundleJson, U as ARKME_DEFAULT_SHARE_WEBSITE, V as ArkmeService, W as ARKME_PROVIDER_CONTRACT_VERSION, X as isArkmeBotAvatarRef, Y as ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES, Z as ArkmePluginError, _ as verifyExtensionResolutionSignature, c as quarantinePersistentExtension, d as writePersistentExtensionActivation, f as renderArkmeBundleClientBundle, g as verifyBundleResolutionSignature, h as arkmeClientContentDigestFromSource, i as invokePersistentArkmeExtension, j as renderArkmeSandboxHostEntry, k as packLocalNativeBundleDirectoryV3, l as readPersistentExtensionActivation, m as arkmeClientContentDigest, o as persistentArkmeExtensionRuntimeState, p as activeProfileExtensionOwnerConflicts, r as deactivatePersistentArkmeExtension, s as materializePersistentExtensionBundle, t as activatePersistentArkmeExtension, u as refreshPersistentClientWrapper, v as verifyNativeBundleResolutionSignature, w as bundleSha256, x as ARKME_NATIVE_BUNDLE_ARTIFACT_KIND, y as ARKME_BUNDLE_ARTIFACT_KIND } from "./persistent-runtime-
|
|
2
|
+
import { A as readNativeBundleTarballV3, B as ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE, C as arkmeSandboxEntryId, D as inspectNativeBundleArtifactV3, E as inspectBundleArtifact, F as unpackArkmeExtension, H as validateVoiceprintPcm16Wav, I as ARKME_EXTENSION_FORMAT, J as ARKME_WORLD_PUBLISH_MAX_IMAGES, M as assertExtensionArtifactSize, N as canonicalExtensionJson, O as packBundleFiles, P as sha256Hex, Q as ArkmeOutgoingCallError, S as ArkmeBundleArtifactError, T as canonicalBundleJson, U as ARKME_DEFAULT_SHARE_WEBSITE, V as ArkmeService, W as ARKME_PROVIDER_CONTRACT_VERSION, X as isArkmeBotAvatarRef, Y as ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES, Z as ArkmePluginError, _ as verifyExtensionResolutionSignature, c as quarantinePersistentExtension, d as writePersistentExtensionActivation, f as renderArkmeBundleClientBundle, g as verifyBundleResolutionSignature, h as arkmeClientContentDigestFromSource, i as invokePersistentArkmeExtension, j as renderArkmeSandboxHostEntry, k as packLocalNativeBundleDirectoryV3, l as readPersistentExtensionActivation, m as arkmeClientContentDigest, o as persistentArkmeExtensionRuntimeState, p as activeProfileExtensionOwnerConflicts, r as deactivatePersistentArkmeExtension, s as materializePersistentExtensionBundle, t as activatePersistentArkmeExtension, u as refreshPersistentClientWrapper, v as verifyNativeBundleResolutionSignature, w as bundleSha256, x as ARKME_NATIVE_BUNDLE_ARTIFACT_KIND, y as ARKME_BUNDLE_ARTIFACT_KIND } from "./persistent-runtime-CaPUsLwg.js";
|
|
3
3
|
import { _ as validatePluginUpdateArtifactOrigin, d as ARKME_PLUGIN_PACKAGE_NAME, f as PluginUpdateArtifactError, g as pluginUpdateEndpointUrl, h as parsePluginUpdateManifest, m as existingCachedPluginArtifactPath, n as buildTargetInstallArgs, o as reconcilePluginUpdaterProfilePolicy, p as downloadAndCachePluginArtifact, t as assertTargetArtifactIntegrity, u as PluginUpdateInstallStateStore, v as validatePluginUpdateServiceOrigin } from "./plugin-updater-helper-Lmz7W2ph.js";
|
|
4
4
|
import { i as invokeArkmeBundle, n as arkmeBundleActive, r as deactivateArkmeBundle } from "./bundle-runtime-BTzRlc6V.js";
|
|
5
5
|
import { t as ArkmeExtensionInstallStore } from "./install-store-C1tAM346.js";
|
|
@@ -1416,6 +1416,25 @@ function botAvatarParam(params) {
|
|
|
1416
1416
|
if (!isArkmeBotAvatarRef(avatar)) throw new ArkmePluginError("bot-avatar-invalid", "Bot 头像引用无效", false, 400);
|
|
1417
1417
|
return avatar;
|
|
1418
1418
|
}
|
|
1419
|
+
function botManageUpdateInputParam(params) {
|
|
1420
|
+
const rawSecurity = params.webhookSecurity;
|
|
1421
|
+
const security = rawSecurity !== null && typeof rawSecurity === "object" && !Array.isArray(rawSecurity) ? rawSecurity : void 0;
|
|
1422
|
+
const avatar = botAvatarParam(params);
|
|
1423
|
+
const mentionEntryEnabled = typeof params.mentionEntryEnabled === "boolean" ? params.mentionEntryEnabled : void 0;
|
|
1424
|
+
return {
|
|
1425
|
+
name: stringParam(params, "name"),
|
|
1426
|
+
description: stringParam(params, "description"),
|
|
1427
|
+
...avatar === "" ? {} : { avatar },
|
|
1428
|
+
...mentionEntryEnabled === void 0 ? {} : { mentionEntryEnabled },
|
|
1429
|
+
...security === void 0 ? {} : { webhookSecurity: {
|
|
1430
|
+
keywordEnabled: security.keywordEnabled === true,
|
|
1431
|
+
keyword: stringParam(security, "keyword"),
|
|
1432
|
+
tokenEnabled: security.tokenEnabled === true,
|
|
1433
|
+
ipWhitelistEnabled: security.ipWhitelistEnabled === true,
|
|
1434
|
+
ipWhitelist: Array.isArray(security.ipWhitelist) ? security.ipWhitelist.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item !== "").slice(0, 100) : []
|
|
1435
|
+
} }
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1419
1438
|
function requiredBooleanParam(params, key) {
|
|
1420
1439
|
const value = params[key];
|
|
1421
1440
|
if (typeof value !== "boolean") throw new ArkmePluginError("boolean-param-required", `${key}必须是布尔值`, false, 400);
|
|
@@ -1777,6 +1796,9 @@ async function dispatchArkmeHostOperation(service, operation, params, updateMana
|
|
|
1777
1796
|
case "directory.contact.open-chat": return await service.openDirectoryContactChat(stringParam(params, "contactRef").trim());
|
|
1778
1797
|
case "directory.group.open-chat": return await service.openDirectoryGroupChat(stringParam(params, "sourceRef").trim(), requestSignal);
|
|
1779
1798
|
case "directory.bot.open-chat": return await service.openBotChat(stringParam(params, "botRef").trim(), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1799
|
+
case "bots.private-chat.open": return await service.openBotPrivateChat(stringParam(params, "botRef").trim(), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1800
|
+
case "bots.private-chat.directory": return await service.listBotPrivateChatDirectory(requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1801
|
+
case "bots.private-chat.send": return await service.sendBotPrivateChatMessage(stringParam(params, "botRef").trim(), stringParam(params, "content"), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1780
1802
|
case "unmarked-speakers.options": return await service.unmarkedSpeakerOptions(stringParam(params, "candidateRef").trim());
|
|
1781
1803
|
case "unmarked-speakers.retry-inference": return await service.retryUnmarkedSpeakerInference(stringParam(params, "candidateRef").trim());
|
|
1782
1804
|
case "unmarked-speakers.segments": {
|
|
@@ -1798,6 +1820,12 @@ async function dispatchArkmeHostOperation(service, operation, params, updateMana
|
|
|
1798
1820
|
});
|
|
1799
1821
|
}
|
|
1800
1822
|
case "bots.list": return await service.listBots(requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1823
|
+
case "bots.manage.profile": return await service.manageBotProfile(stringParam(params, "botRef").trim(), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1824
|
+
case "bots.manage.update": return await service.updateManagedBot(stringParam(params, "botRef").trim(), botManageUpdateInputParam(params), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1825
|
+
case "bots.manage.reveal-token": return await service.revealManagedBotToken(stringParam(params, "botRef").trim(), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1826
|
+
case "bots.manage.delete": return await service.deleteManagedBot(stringParam(params, "botRef").trim(), stringParam(params, "confirmationName"), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1827
|
+
case "bots.private-chat.notification.status": return await service.botNotificationPreference(stringParam(params, "botRef").trim(), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1828
|
+
case "bots.private-chat.notification.update": return await service.updateBotNotificationPreference(stringParam(params, "botRef").trim(), booleanParam(params, "muted"), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
1801
1829
|
case "recordings.calendar": return await service.recordingCalendar(numberParam(params, "fromStamp", 0), numberParam(params, "toStamp", 0));
|
|
1802
1830
|
case "recordings.day": return await service.recordingDay(numberParam(params, "dateStamp", 0));
|
|
1803
1831
|
case "calendar.buckets": return await service.calendarBuckets({
|
|
@@ -1983,6 +2011,11 @@ async function dispatchArkmeHostOperation(service, operation, params, updateMana
|
|
|
1983
2011
|
...stringParam(params, "cursor") === "" ? {} : { cursor: stringParam(params, "cursor") },
|
|
1984
2012
|
refresh: booleanParam(params, "refresh")
|
|
1985
2013
|
});
|
|
2014
|
+
case "source.directory.policy.set": return await service.setChatDirectoryPolicy(stringParam(params, "sourceRef"), {
|
|
2015
|
+
...typeof params.pinned === "boolean" ? { pinned: params.pinned } : {},
|
|
2016
|
+
...typeof params.hidden === "boolean" ? { hidden: params.hidden } : {},
|
|
2017
|
+
...requestSignal === void 0 ? {} : { signal: requestSignal }
|
|
2018
|
+
});
|
|
1986
2019
|
case "source.timeline": {
|
|
1987
2020
|
const cursor = timelineCursorParam(params);
|
|
1988
2021
|
return await service.readSource(stringParam(params, "sourceRef"), {
|
|
@@ -14215,6 +14248,7 @@ function validateConfig(ctx, config) {
|
|
|
14215
14248
|
if (config.environment === "prod") {
|
|
14216
14249
|
if ([
|
|
14217
14250
|
config.authBaseUrl,
|
|
14251
|
+
config.subjectBaseUrl,
|
|
14218
14252
|
config.recordBaseUrl,
|
|
14219
14253
|
config.dataBaseUrl,
|
|
14220
14254
|
config.chatBaseUrl,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as persistentArkmeExtensionActive, i as invokePersistentArkmeExtension, n as applyPersistentArkmeHostExtension, o as persistentArkmeExtensionRuntimeState, r as deactivatePersistentArkmeExtension, t as activatePersistentArkmeExtension } from "./persistent-runtime-
|
|
1
|
+
import { a as persistentArkmeExtensionActive, i as invokePersistentArkmeExtension, n as applyPersistentArkmeHostExtension, o as persistentArkmeExtensionRuntimeState, r as deactivatePersistentArkmeExtension, t as activatePersistentArkmeExtension } from "./persistent-runtime-CaPUsLwg.js";
|
|
2
2
|
export { activatePersistentArkmeExtension, applyPersistentArkmeHostExtension, deactivatePersistentArkmeExtension, invokePersistentArkmeExtension, persistentArkmeExtensionActive, persistentArkmeExtensionRuntimeState };
|
|
@@ -3146,6 +3146,15 @@ function arkmeGroupBotBindingBody(source) {
|
|
|
3146
3146
|
if (target?.subjectUid !== void 0 && target.subjectUid.trim() !== "") return { subject_uid: target.subjectUid.trim() };
|
|
3147
3147
|
return { subject_uid: source.ownerRef };
|
|
3148
3148
|
}
|
|
3149
|
+
function arkmeChatSidebarTargetFromBundle(bundle, fallbackSubjectUid = "") {
|
|
3150
|
+
const chatSession = objectValue$1(bundle.session);
|
|
3151
|
+
const subjectUid = stringValue$1(bundle.subject_uid ?? bundle.subjectUid ?? bundle.topic_uid ?? bundle.topicUid ?? chatSession.subject_uid ?? chatSession.subjectUid ?? chatSession.topic_uid ?? chatSession.topicUid ?? fallbackSubjectUid).trim();
|
|
3152
|
+
if (subjectUid === "") return void 0;
|
|
3153
|
+
return {
|
|
3154
|
+
subjectUid,
|
|
3155
|
+
hiddenAnchorTimestamp: Math.max(0, numberValue$20(bundle.sort_active_at ?? bundle.last_active_at ?? chatSession.last_active_at))
|
|
3156
|
+
};
|
|
3157
|
+
}
|
|
3149
3158
|
function backendBooleanValue(value) {
|
|
3150
3159
|
if (value === null || value === void 0) return void 0;
|
|
3151
3160
|
if (typeof value === "boolean") return value;
|
|
@@ -3760,6 +3769,62 @@ var SourceService = class {
|
|
|
3760
3769
|
if (this.sourceListInFlight.get(cacheKey) === pending) this.sourceListInFlight.delete(cacheKey);
|
|
3761
3770
|
}
|
|
3762
3771
|
}
|
|
3772
|
+
async setChatDirectoryPolicy(sourceRef, options = {}) {
|
|
3773
|
+
const session = await this.runtime.requireSession();
|
|
3774
|
+
const source = await this.openSourceRef(sourceRef, session.userId);
|
|
3775
|
+
if (source.kind !== "private_chat" && source.kind !== "group_chat") throw new ArkmePluginError("chat-directory-policy-invalid", "仅支持更新私聊或群聊的会话列表状态", false);
|
|
3776
|
+
const sidebarTarget = await this.resolveChatSidebarTarget(source, session, options.signal);
|
|
3777
|
+
const current = await this.runtime.authenticatedChatPost("/api/v1/chats/policy/get", { chat_session_uid: source.ownerRef }, session, options.signal);
|
|
3778
|
+
const pinned = options.pinned ?? numberValue$20(current.pin_state) === 2;
|
|
3779
|
+
const hidden = options.hidden ?? numberValue$20(current.show_in_home_state) === 2;
|
|
3780
|
+
const updatedAt = Date.now();
|
|
3781
|
+
const writes = [this.runtime.authenticatedChatPost("/api/v1/chats/policy/update", {
|
|
3782
|
+
chat_session_uid: source.ownerRef,
|
|
3783
|
+
show_in_home_state: hidden ? 2 : 1,
|
|
3784
|
+
privacy_state: numberValue$20(current.privacy_state) || 1,
|
|
3785
|
+
mute_state: numberValue$20(current.mute_state) || 1,
|
|
3786
|
+
pin_state: pinned ? 2 : 1,
|
|
3787
|
+
notify_state: numberValue$20(current.notify_state) || 1,
|
|
3788
|
+
status: numberValue$20(current.status) || 1,
|
|
3789
|
+
update_at: updatedAt
|
|
3790
|
+
}, session, options.signal)];
|
|
3791
|
+
if (options.hidden !== void 0) writes.push(this.runtime.authenticatedSubjectPost("/api/v1/subject/batch-set-sidebar-hidden-status", { items: [{
|
|
3792
|
+
subject_uid: sidebarTarget.subjectUid,
|
|
3793
|
+
hidden,
|
|
3794
|
+
hidden_anchor_timestamp: hidden ? Math.max(1, sidebarTarget.hiddenAnchorTimestamp || updatedAt) : 0
|
|
3795
|
+
}] }, session, options.signal));
|
|
3796
|
+
if (options.pinned !== void 0) writes.push(this.runtime.authenticatedPost("/api/v1/topics/pin/set", {
|
|
3797
|
+
topic_uid: sidebarTarget.subjectUid,
|
|
3798
|
+
pin_state: pinned ? 1 : 2,
|
|
3799
|
+
...pinned ? { pinned_at: updatedAt } : {}
|
|
3800
|
+
}, session, options.signal));
|
|
3801
|
+
await Promise.all(writes);
|
|
3802
|
+
const cacheKey = `${String(session.userId)}:${source.ownerRef}`;
|
|
3803
|
+
const cached = this.chatSourceCache.get(cacheKey);
|
|
3804
|
+
if (cached !== void 0) this.chatSourceCache.set(cacheKey, {
|
|
3805
|
+
...cached,
|
|
3806
|
+
isPinned: pinned
|
|
3807
|
+
});
|
|
3808
|
+
this.sourceListCache.clear();
|
|
3809
|
+
return {
|
|
3810
|
+
sourceRef,
|
|
3811
|
+
pinned,
|
|
3812
|
+
hidden
|
|
3813
|
+
};
|
|
3814
|
+
}
|
|
3815
|
+
async resolveChatSidebarTarget(source, session, signal) {
|
|
3816
|
+
if (source.sidebarSubjectUid !== void 0 && source.sidebarSubjectUid.trim() !== "") return {
|
|
3817
|
+
subjectUid: source.sidebarSubjectUid.trim(),
|
|
3818
|
+
hiddenAnchorTimestamp: Math.max(0, source.sidebarHiddenAnchorTimestamp ?? 0)
|
|
3819
|
+
};
|
|
3820
|
+
const target = arkmeChatSidebarTargetFromBundle(await this.runtime.authenticatedChatPost("/api/v1/chats/detail", { chat_session_uid: source.ownerRef }, session, signal, {
|
|
3821
|
+
lane: "interactive-read",
|
|
3822
|
+
key: `chat-sidebar-target:${source.ownerRef}`,
|
|
3823
|
+
failureCooldownMs: 2e3
|
|
3824
|
+
}), source.kind === "group_chat" ? source.ownerRef : "");
|
|
3825
|
+
if (target === void 0) throw new ArkmePluginError("chat-sidebar-target-unavailable", "未能定位该会话的跨端侧边栏数据,请刷新后重试", true, 502);
|
|
3826
|
+
return target;
|
|
3827
|
+
}
|
|
3763
3828
|
async listGroupSources(options = {}) {
|
|
3764
3829
|
const session = await this.runtime.requireSession();
|
|
3765
3830
|
const limit = Math.min(50, Math.max(1, Math.trunc(options.limit ?? 30)));
|
|
@@ -3934,7 +3999,9 @@ var SourceService = class {
|
|
|
3934
3999
|
const latestRecord = objectValue$1(latestPreview.record);
|
|
3935
4000
|
const latestPayload = objectValue$1(latestRecord.payload);
|
|
3936
4001
|
const unread = objectValue$1(bundle.unread_snapshot);
|
|
3937
|
-
const
|
|
4002
|
+
const currentPolicy = objectValue$1(bundle.current_policy);
|
|
4003
|
+
const isMuted = chatMessageDnd$1(currentPolicy) ?? false;
|
|
4004
|
+
const isPinned = numberValue$20(currentPolicy.pin_state) === 2;
|
|
3938
4005
|
const uid = stringValue$1(chatSession.chat_session_uid).trim();
|
|
3939
4006
|
const sessionKind = numberValue$20(chatSession.session_kind);
|
|
3940
4007
|
const kind = sessionKind === 2 ? "group_chat" : sessionKind === 1 || sessionKind === 3 ? "private_chat" : void 0;
|
|
@@ -3947,8 +4014,12 @@ var SourceService = class {
|
|
|
3947
4014
|
const backendMentionState = chatUnreadMentionState(unread);
|
|
3948
4015
|
const hasUnreadMention = kind !== "group_chat" ? void 0 : unreadCount <= 0 ? false : backendMentionState === void 0 && !latestPreviewMentionsViewer ? void 0 : backendMentionState === true || latestPreviewMentionsViewer;
|
|
3949
4016
|
const botGroupTarget = kind === "group_chat" ? arkmeGroupBotBindingTargetFromBundle(bundle) : void 0;
|
|
4017
|
+
const sidebarTarget = arkmeChatSidebarTargetFromBundle(bundle, kind === "group_chat" ? uid : "");
|
|
3950
4018
|
const item = {
|
|
3951
|
-
sourceRef: await this.sealSourceRef(session.userId, kind, uid, displayName,
|
|
4019
|
+
sourceRef: await this.sealSourceRef(session.userId, kind, uid, displayName, {
|
|
4020
|
+
...botGroupTarget === void 0 ? {} : { botGroupTarget },
|
|
4021
|
+
...sidebarTarget === void 0 ? {} : { sidebarTarget }
|
|
4022
|
+
}),
|
|
3952
4023
|
sourceKey: await this.chatDirectorySourceKey(session.userId, uid),
|
|
3953
4024
|
kind,
|
|
3954
4025
|
displayName,
|
|
@@ -3957,6 +4028,7 @@ var SourceService = class {
|
|
|
3957
4028
|
unreadCount,
|
|
3958
4029
|
...hasUnreadMention === void 0 ? {} : { hasUnreadMention },
|
|
3959
4030
|
isMuted,
|
|
4031
|
+
isPinned,
|
|
3960
4032
|
...numberValue$20(unread.session_last_seq ?? chatSession.last_seq) > 0 ? { latestSequence: numberValue$20(unread.session_last_seq ?? chatSession.last_seq) } : {}
|
|
3961
4033
|
};
|
|
3962
4034
|
const itemIndex = items.push(item) - 1;
|
|
@@ -4089,13 +4161,18 @@ var SourceService = class {
|
|
|
4089
4161
|
}
|
|
4090
4162
|
async sealSourceRef(userId, kind, ownerRef, displayName, options = {}) {
|
|
4091
4163
|
const botGroupTarget = kind === "group_chat" ? sanitizeGroupBotBindingTarget(options.botGroupTarget) : void 0;
|
|
4164
|
+
const sidebarTarget = kind === "private_chat" || kind === "group_chat" ? options.sidebarTarget : void 0;
|
|
4092
4165
|
const payload = encodeOpaqueJson$6({
|
|
4093
4166
|
version: 1,
|
|
4094
4167
|
userId,
|
|
4095
4168
|
kind,
|
|
4096
4169
|
ownerRef,
|
|
4097
4170
|
displayName,
|
|
4098
|
-
...botGroupTarget === void 0 ? {} : { botGroupTarget }
|
|
4171
|
+
...botGroupTarget === void 0 ? {} : { botGroupTarget },
|
|
4172
|
+
...sidebarTarget === void 0 ? {} : {
|
|
4173
|
+
sidebarSubjectUid: sidebarTarget.subjectUid,
|
|
4174
|
+
sidebarHiddenAnchorTimestamp: sidebarTarget.hiddenAnchorTimestamp
|
|
4175
|
+
}
|
|
4099
4176
|
});
|
|
4100
4177
|
return `arkme-source-v1.${payload}.${createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(payload).digest("base64url")}`;
|
|
4101
4178
|
}
|
|
@@ -4122,6 +4199,14 @@ var SourceService = class {
|
|
|
4122
4199
|
...kind === "group_chat" ? (() => {
|
|
4123
4200
|
const botGroupTarget = sanitizeGroupBotBindingTarget(parsed.botGroupTarget);
|
|
4124
4201
|
return botGroupTarget === void 0 ? {} : { botGroupTarget };
|
|
4202
|
+
})() : {},
|
|
4203
|
+
...kind === "private_chat" || kind === "group_chat" ? (() => {
|
|
4204
|
+
const sidebarSubjectUid = stringValue$1(parsed.sidebarSubjectUid).trim();
|
|
4205
|
+
const sidebarHiddenAnchorTimestamp = Math.max(0, numberValue$20(parsed.sidebarHiddenAnchorTimestamp));
|
|
4206
|
+
return sidebarSubjectUid === "" ? {} : {
|
|
4207
|
+
sidebarSubjectUid,
|
|
4208
|
+
sidebarHiddenAnchorTimestamp
|
|
4209
|
+
};
|
|
4125
4210
|
})() : {}
|
|
4126
4211
|
};
|
|
4127
4212
|
if (parsed.version !== 1 || result.userId !== expectedUserId || !isSourceKind(kind) || result.ownerRef === "" || result.displayName === "") throw new ArkmePluginError("source-ref-invalid", "Arkme 数据源引用与当前账号不匹配", false, 403);
|
|
@@ -4130,7 +4215,13 @@ var SourceService = class {
|
|
|
4130
4215
|
async sourceItem(source) {
|
|
4131
4216
|
const sourceKey = source.kind === "private_chat" || source.kind === "group_chat" ? await this.chatDirectorySourceKey(source.userId, source.ownerRef) : void 0;
|
|
4132
4217
|
return {
|
|
4133
|
-
sourceRef: await this.sealSourceRef(source.userId, source.kind, source.ownerRef, source.displayName,
|
|
4218
|
+
sourceRef: await this.sealSourceRef(source.userId, source.kind, source.ownerRef, source.displayName, {
|
|
4219
|
+
...source.botGroupTarget === void 0 ? {} : { botGroupTarget: source.botGroupTarget },
|
|
4220
|
+
...source.sidebarSubjectUid === void 0 ? {} : { sidebarTarget: {
|
|
4221
|
+
subjectUid: source.sidebarSubjectUid,
|
|
4222
|
+
hiddenAnchorTimestamp: source.sidebarHiddenAnchorTimestamp ?? 0
|
|
4223
|
+
} }
|
|
4224
|
+
}),
|
|
4134
4225
|
...sourceKey === void 0 ? {} : { sourceKey },
|
|
4135
4226
|
kind: source.kind,
|
|
4136
4227
|
displayName: source.displayName,
|
|
@@ -4143,7 +4234,9 @@ var SourceService = class {
|
|
|
4143
4234
|
const counterpart = objectValue$1(bundle.private_counterpart);
|
|
4144
4235
|
const supplement = objectValue$1(bundle.private_supplement);
|
|
4145
4236
|
const unread = objectValue$1(bundle.unread_snapshot);
|
|
4146
|
-
const
|
|
4237
|
+
const currentPolicy = objectValue$1(bundle.current_policy);
|
|
4238
|
+
const isMuted = chatMessageDnd$1(currentPolicy) ?? cached?.isMuted ?? false;
|
|
4239
|
+
const isPinned = numberValue$20(currentPolicy.pin_state) === 2;
|
|
4147
4240
|
const uid = stringValue$1(chatSession.chat_session_uid).trim();
|
|
4148
4241
|
const sessionKind = numberValue$20(chatSession.session_kind);
|
|
4149
4242
|
const kind = sessionKind === 2 ? "group_chat" : sessionKind === 1 || sessionKind === 3 ? "private_chat" : void 0;
|
|
@@ -4157,8 +4250,12 @@ var SourceService = class {
|
|
|
4157
4250
|
const backendMentionState = chatUnreadMentionState(unread);
|
|
4158
4251
|
const hasUnreadMention = kind !== "group_chat" ? void 0 : unreadCount <= 0 ? false : backendMentionState === void 0 && !latestMentionsViewer ? cached?.hasUnreadMention : backendMentionState === true || latestMentionsViewer;
|
|
4159
4252
|
const botGroupTarget = kind === "group_chat" ? arkmeGroupBotBindingTargetFromBundle(bundle) : void 0;
|
|
4253
|
+
const sidebarTarget = arkmeChatSidebarTargetFromBundle(bundle, kind === "group_chat" ? uid : "");
|
|
4160
4254
|
return {
|
|
4161
|
-
sourceRef: await this.sealSourceRef(session.userId, kind, uid, displayName,
|
|
4255
|
+
sourceRef: await this.sealSourceRef(session.userId, kind, uid, displayName, {
|
|
4256
|
+
...botGroupTarget === void 0 ? {} : { botGroupTarget },
|
|
4257
|
+
...sidebarTarget === void 0 ? {} : { sidebarTarget }
|
|
4258
|
+
}),
|
|
4162
4259
|
sourceKey: await this.chatDirectorySourceKey(session.userId, uid),
|
|
4163
4260
|
kind,
|
|
4164
4261
|
displayName,
|
|
@@ -4170,6 +4267,7 @@ var SourceService = class {
|
|
|
4170
4267
|
unreadCount,
|
|
4171
4268
|
...hasUnreadMention === void 0 ? {} : { hasUnreadMention },
|
|
4172
4269
|
isMuted,
|
|
4270
|
+
isPinned,
|
|
4173
4271
|
...latestSequence > 0 ? { latestSequence } : {}
|
|
4174
4272
|
};
|
|
4175
4273
|
}
|
|
@@ -4224,6 +4322,93 @@ function arkmeNormalizeBotProvider(value) {
|
|
|
4224
4322
|
const normalized = stringValue$1(value).trim().toLowerCase();
|
|
4225
4323
|
if (normalized === "openclaw" || normalized === "webhook") return normalized;
|
|
4226
4324
|
}
|
|
4325
|
+
const BOT_CHAT_SESSION_UID_KEYS = [
|
|
4326
|
+
"chat_session_uid",
|
|
4327
|
+
"chatSessionUid",
|
|
4328
|
+
"direct_chat_session_uid",
|
|
4329
|
+
"directChatSessionUid",
|
|
4330
|
+
"private_chat_session_uid",
|
|
4331
|
+
"privateChatSessionUid"
|
|
4332
|
+
];
|
|
4333
|
+
/** Read the standard-session aliases accepted by the Flutter desktop client. */
|
|
4334
|
+
function botChatSessionUid(data) {
|
|
4335
|
+
const read = (value, allowUid = false) => {
|
|
4336
|
+
for (const key of BOT_CHAT_SESSION_UID_KEYS) {
|
|
4337
|
+
const candidate = stringValue$1(value[key]).trim();
|
|
4338
|
+
if (candidate !== "" && candidate !== "null") return candidate;
|
|
4339
|
+
}
|
|
4340
|
+
const uid = allowUid ? stringValue$1(value.uid).trim() : "";
|
|
4341
|
+
return uid !== "" && uid !== "null" ? uid : void 0;
|
|
4342
|
+
};
|
|
4343
|
+
const direct = read(data);
|
|
4344
|
+
if (direct !== void 0) return direct;
|
|
4345
|
+
for (const key of [
|
|
4346
|
+
"chat_session",
|
|
4347
|
+
"direct_chat_session",
|
|
4348
|
+
"private_chat_session"
|
|
4349
|
+
]) {
|
|
4350
|
+
const nested = read(objectValue$1(data[key]), true);
|
|
4351
|
+
if (nested !== void 0) return nested;
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
/**
|
|
4355
|
+
* Flutter accepts the legacy `session_id` returned by the Bot endpoint only
|
|
4356
|
+
* after proving it resolves to a chat session. Keep the same guard here: a
|
|
4357
|
+
* bot id (or a raw Bot topic id) must never become a generic chat source.
|
|
4358
|
+
*/
|
|
4359
|
+
function legacyBotChatSessionCandidate(value, botId) {
|
|
4360
|
+
const candidate = stringValue$1(value).trim();
|
|
4361
|
+
if (candidate === "" || candidate === botId) return void 0;
|
|
4362
|
+
if (candidate.includes("_bot") && !candidate.startsWith("chat_session_")) return void 0;
|
|
4363
|
+
return candidate;
|
|
4364
|
+
}
|
|
4365
|
+
function botPrivateChatTimestamp(value) {
|
|
4366
|
+
const numeric = numberValue$19(value);
|
|
4367
|
+
if (numeric <= 0) return 0;
|
|
4368
|
+
if (numeric < 1e10) return numeric * 1e3;
|
|
4369
|
+
let millis = numeric;
|
|
4370
|
+
while (millis >= 0x5af3107a4000) millis = Math.trunc(millis / 1e3);
|
|
4371
|
+
return millis;
|
|
4372
|
+
}
|
|
4373
|
+
function botWebhookSecurity(value) {
|
|
4374
|
+
const raw = objectValue$1(value);
|
|
4375
|
+
return {
|
|
4376
|
+
keywordEnabled: booleanValue$10(raw.keyword_enabled),
|
|
4377
|
+
keyword: stringValue$1(raw.keyword).trim(),
|
|
4378
|
+
tokenEnabled: booleanValue$10(raw.token_enabled ?? raw.signature_enabled),
|
|
4379
|
+
ipWhitelistEnabled: booleanValue$10(raw.ip_whitelist_enabled),
|
|
4380
|
+
ipWhitelist: listValue$20(raw.ip_whitelist).map((item) => stringValue$1(item).trim()).filter((item) => item !== "").slice(0, 100)
|
|
4381
|
+
};
|
|
4382
|
+
}
|
|
4383
|
+
function botProfileSource(data) {
|
|
4384
|
+
const bot = objectValue$1(data.bot);
|
|
4385
|
+
return Object.keys(bot).length === 0 ? data : bot;
|
|
4386
|
+
}
|
|
4387
|
+
function botProfileSubjectUid(data) {
|
|
4388
|
+
const bot = botProfileSource(data);
|
|
4389
|
+
return stringValue$1(bot.subject_uid ?? bot.topic_uid ?? data.subject_uid ?? data.topic_uid).trim();
|
|
4390
|
+
}
|
|
4391
|
+
function botPrivateChatMessage(value, fallbackContent = "") {
|
|
4392
|
+
const raw = objectValue$1(value);
|
|
4393
|
+
return {
|
|
4394
|
+
role: stringValue$1(raw.role).trim().toLowerCase() === "user" ? "user" : "assistant",
|
|
4395
|
+
content: stringValue$1(raw.content).trim() || fallbackContent,
|
|
4396
|
+
status: stringValue$1(raw.status).trim() || "sent",
|
|
4397
|
+
createdAtMillis: botPrivateChatTimestamp(raw.created_at ?? raw.createdAt)
|
|
4398
|
+
};
|
|
4399
|
+
}
|
|
4400
|
+
function botWithPrivateChatActivity(bot, messages) {
|
|
4401
|
+
const latest = messages.reduce((current, message) => {
|
|
4402
|
+
if (current === void 0 || message.createdAtMillis >= current.createdAtMillis) return message;
|
|
4403
|
+
return current;
|
|
4404
|
+
}, void 0);
|
|
4405
|
+
if (latest === void 0) return bot;
|
|
4406
|
+
return {
|
|
4407
|
+
...bot,
|
|
4408
|
+
...latest.createdAtMillis > 0 ? { latestMessageAtMillis: latest.createdAtMillis } : {},
|
|
4409
|
+
...latest.content === "" ? {} : { latestMessagePreview: latest.content }
|
|
4410
|
+
};
|
|
4411
|
+
}
|
|
4227
4412
|
var BotService = class {
|
|
4228
4413
|
runtime;
|
|
4229
4414
|
source;
|
|
@@ -4328,22 +4513,141 @@ var BotService = class {
|
|
|
4328
4513
|
if (!token.startsWith("jbot_")) throw new ArkmePluginError("bot-token-contract-invalid", "Bot 凭据响应无效", false, 502);
|
|
4329
4514
|
return new SecretValue(token);
|
|
4330
4515
|
}
|
|
4516
|
+
async manageBotProfile(botRef, options = {}) {
|
|
4517
|
+
const session = await this.runtime.requireSession();
|
|
4518
|
+
const reference = await this.openBotRef(botRef, session.userId);
|
|
4519
|
+
const data = await this.runtime.authenticatedBotPost("/api/v1/bot/profile", { bot_id: reference.botId }, session, options.signal);
|
|
4520
|
+
return await this.botManageProfileFromData(data, session.userId);
|
|
4521
|
+
}
|
|
4522
|
+
async updateManagedBot(botRef, input, options = {}) {
|
|
4523
|
+
const name = input.name.trim();
|
|
4524
|
+
const description = input.description.trim();
|
|
4525
|
+
if (name === "" || [...name].length > 50) throw new ArkmePluginError("bot-name-invalid", "Bot 名称需为 1-50 个字符", false, 400);
|
|
4526
|
+
if ([...description].length > 200) throw new ArkmePluginError("bot-description-invalid", "Bot 简介不能超过 200 个字符", false, 400);
|
|
4527
|
+
if (input.avatar !== void 0 && !isArkmeBotAvatarRef(input.avatar)) throw new ArkmePluginError("bot-avatar-invalid", "Bot 头像引用无效", false, 400);
|
|
4528
|
+
const session = await this.runtime.requireSession();
|
|
4529
|
+
const reference = await this.openBotRef(botRef, session.userId);
|
|
4530
|
+
const current = botProfileSource(await this.runtime.authenticatedBotPost("/api/v1/bot/profile", { bot_id: reference.botId }, session, options.signal));
|
|
4531
|
+
const provider = arkmeNormalizeBotProvider(current.provider);
|
|
4532
|
+
if (provider === void 0) throw new ArkmePluginError("bot-contract-invalid", "Bot 配置响应不完整", true, 502);
|
|
4533
|
+
const security = input.webhookSecurity;
|
|
4534
|
+
if (security !== void 0 && provider !== "webhook") throw new ArkmePluginError("bot-webhook-security-invalid", "仅 Webhook Bot 支持安全设置", false, 400);
|
|
4535
|
+
await this.runtime.authenticatedBotPost("/api/v1/bot/update", {
|
|
4536
|
+
bot_id: reference.botId,
|
|
4537
|
+
name,
|
|
4538
|
+
description,
|
|
4539
|
+
avatar: input.avatar ?? stringValue$1(current.avatar).trim(),
|
|
4540
|
+
...input.mentionEntryEnabled === void 0 ? {} : { mention_entry_enabled: input.mentionEntryEnabled },
|
|
4541
|
+
...security === void 0 ? {} : { webhook_security: {
|
|
4542
|
+
keyword_enabled: security.keywordEnabled,
|
|
4543
|
+
keyword: security.keyword.trim(),
|
|
4544
|
+
token_enabled: security.tokenEnabled,
|
|
4545
|
+
ip_whitelist_enabled: security.ipWhitelistEnabled,
|
|
4546
|
+
ip_whitelist: security.ipWhitelist.map((item) => item.trim()).filter((item) => item !== "").slice(0, 100)
|
|
4547
|
+
} }
|
|
4548
|
+
}, session, options.signal);
|
|
4549
|
+
const refreshed = await this.runtime.authenticatedBotPost("/api/v1/bot/profile", { bot_id: reference.botId }, session, options.signal);
|
|
4550
|
+
return await this.botManageProfileFromData(refreshed, session.userId);
|
|
4551
|
+
}
|
|
4552
|
+
async revealManagedBotToken(botRef, options = {}) {
|
|
4553
|
+
return { token: (await this.revealBotSecret(botRef, options)).reveal() };
|
|
4554
|
+
}
|
|
4555
|
+
async deleteManagedBot(botRef, confirmationName, options = {}) {
|
|
4556
|
+
const session = await this.runtime.requireSession();
|
|
4557
|
+
const reference = await this.openBotRef(botRef, session.userId);
|
|
4558
|
+
const data = await this.runtime.authenticatedBotPost("/api/v1/bot/profile", { bot_id: reference.botId }, session, options.signal);
|
|
4559
|
+
if (confirmationName.trim() !== stringValue$1(botProfileSource(data).name).trim()) throw new ArkmePluginError("bot-delete-confirmation-invalid", "请输入完整 Bot 名称以确认删除", false, 400);
|
|
4560
|
+
await this.runtime.authenticatedBotPost("/api/v1/bot/delete", { bot_id: reference.botId }, session, options.signal);
|
|
4561
|
+
this.deleteBotRef(botRef);
|
|
4562
|
+
}
|
|
4563
|
+
async botNotificationPreference(botRef, options = {}) {
|
|
4564
|
+
const { session, subjectUid } = await this.botNotificationTarget(botRef, options);
|
|
4565
|
+
return { muted: (await this.runtime.authenticatedSubjectPost("/api/v1/subject/get-able-push-status", { subject_uid: subjectUid }, session, options.signal)).able_push === false };
|
|
4566
|
+
}
|
|
4567
|
+
async updateBotNotificationPreference(botRef, muted, options = {}) {
|
|
4568
|
+
const { session, subjectUid } = await this.botNotificationTarget(botRef, options);
|
|
4569
|
+
await this.runtime.authenticatedSubjectPost("/api/v1/subject/set-able-push-status", {
|
|
4570
|
+
subject_uid: subjectUid,
|
|
4571
|
+
able_push: !muted
|
|
4572
|
+
}, session, options.signal);
|
|
4573
|
+
return { muted };
|
|
4574
|
+
}
|
|
4575
|
+
async botNotificationTarget(botRef, options = {}) {
|
|
4576
|
+
const session = await this.runtime.requireSession();
|
|
4577
|
+
const reference = await this.openBotRef(botRef, session.userId);
|
|
4578
|
+
const subjectUid = botProfileSubjectUid(await this.runtime.authenticatedBotPost("/api/v1/bot/profile", { bot_id: reference.botId }, session, options.signal));
|
|
4579
|
+
if (subjectUid === "") throw new ArkmePluginError("bot-notification-unavailable", "当前 Bot 未返回可用私聊通知标识", false, 409);
|
|
4580
|
+
return {
|
|
4581
|
+
session,
|
|
4582
|
+
subjectUid
|
|
4583
|
+
};
|
|
4584
|
+
}
|
|
4585
|
+
async openBotPrivateChat(botRef, options = {}) {
|
|
4586
|
+
const session = await this.runtime.requireSession();
|
|
4587
|
+
const bot = (await this.listBots(options)).items.find((item) => item.botRef === botRef);
|
|
4588
|
+
if (bot === void 0) throw new ArkmePluginError("bot-ref-not-owned", "当前账号不存在该 Bot", false, 404);
|
|
4589
|
+
return await this.openBotPrivateChatForSummary(bot, session, options.signal);
|
|
4590
|
+
}
|
|
4591
|
+
async listBotPrivateChatDirectory(options = {}) {
|
|
4592
|
+
const session = await this.runtime.requireSession();
|
|
4593
|
+
const { items } = await this.listBots(options);
|
|
4594
|
+
return { items: await Promise.all(items.map(async (bot) => {
|
|
4595
|
+
try {
|
|
4596
|
+
return (await this.openBotPrivateChatForSummary(bot, session, options.signal)).bot;
|
|
4597
|
+
} catch {
|
|
4598
|
+
return bot;
|
|
4599
|
+
}
|
|
4600
|
+
})) };
|
|
4601
|
+
}
|
|
4602
|
+
async openBotPrivateChatForSummary(bot, session, signal) {
|
|
4603
|
+
const reference = await this.openBotRef(bot.botRef, session.userId);
|
|
4604
|
+
const messages = listValue$20((await this.runtime.authenticatedBotPost("/api/v1/bot/private-chat/open", { bot_id: reference.botId }, session, signal)).messages).map((message) => botPrivateChatMessage(message));
|
|
4605
|
+
return {
|
|
4606
|
+
bot: botWithPrivateChatActivity(bot, messages),
|
|
4607
|
+
messages
|
|
4608
|
+
};
|
|
4609
|
+
}
|
|
4610
|
+
async sendBotPrivateChatMessage(botRef, contentInput, options = {}) {
|
|
4611
|
+
const content = contentInput.trim();
|
|
4612
|
+
if (content === "") throw new ArkmePluginError("bot-private-chat-content-invalid", "请输入消息内容", false, 400);
|
|
4613
|
+
if (content.length > 2e4) throw new ArkmePluginError("bot-private-chat-content-invalid", "消息不能超过 20000 个字符", false, 400);
|
|
4614
|
+
const session = await this.runtime.requireSession();
|
|
4615
|
+
const reference = await this.openBotRef(botRef, session.userId);
|
|
4616
|
+
const data = await this.runtime.authenticatedBotPost("/api/v1/bot/private-chat/message/send", {
|
|
4617
|
+
bot_id: reference.botId,
|
|
4618
|
+
content
|
|
4619
|
+
}, session, options.signal);
|
|
4620
|
+
const botMessages = [...listValue$20(data.bot_messages).map((message) => botPrivateChatMessage(message)), ...Object.keys(objectValue$1(data.bot_message)).length === 0 ? [] : [botPrivateChatMessage(data.bot_message)]];
|
|
4621
|
+
return {
|
|
4622
|
+
userMessage: botPrivateChatMessage(data.user_message, content),
|
|
4623
|
+
botMessages,
|
|
4624
|
+
status: stringValue$1(data.status).trim() || "ok"
|
|
4625
|
+
};
|
|
4626
|
+
}
|
|
4331
4627
|
async openBotChat(botRef, options = {}) {
|
|
4332
4628
|
const session = await this.runtime.requireSession();
|
|
4333
4629
|
const reference = await this.openBotRef(botRef, session.userId);
|
|
4334
4630
|
const bot = (await this.listBots(options)).items.find((item) => item.botRef === botRef);
|
|
4335
4631
|
if (bot === void 0) throw new ArkmePluginError("bot-ref-not-owned", "当前账号不存在该 OpenClaw Bot", false, 404);
|
|
4336
|
-
const
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4632
|
+
const data = await this.runtime.authenticatedBotPost("/api/v1/bot/private-chat/open", { bot_id: reference.botId }, session, options.signal);
|
|
4633
|
+
const chatSessionUid = botChatSessionUid(data);
|
|
4634
|
+
if (chatSessionUid !== void 0) {
|
|
4635
|
+
const source = {
|
|
4636
|
+
sourceRef: await this.source.sealSourceRef(session.userId, "private_chat", chatSessionUid, bot.name),
|
|
4637
|
+
kind: "private_chat",
|
|
4638
|
+
displayName: bot.name,
|
|
4639
|
+
activeAtMillis: 0,
|
|
4640
|
+
unreadCount: 0
|
|
4641
|
+
};
|
|
4642
|
+
this.source.setChatSourceByKey(`${String(session.userId)}:${chatSessionUid}`, source);
|
|
4643
|
+
return source;
|
|
4644
|
+
}
|
|
4645
|
+
const legacySessionId = legacyBotChatSessionCandidate(data.session_id, reference.botId);
|
|
4646
|
+
if (legacySessionId !== void 0) {
|
|
4647
|
+
const source = await this.source.searchTargetSource(3, legacySessionId, bot.name, options.signal);
|
|
4648
|
+
if (source !== void 0) return source;
|
|
4649
|
+
}
|
|
4650
|
+
throw new ArkmePluginError("bot-chat-source-unavailable", "当前 Bot 私聊未返回可用会话,暂时不能复用统一 source 读写链路", false, 409);
|
|
4347
4651
|
}
|
|
4348
4652
|
async resolveBotConnectionMetadata(botRef, options = {}) {
|
|
4349
4653
|
const session = await this.runtime.requireSession();
|
|
@@ -4454,16 +4758,39 @@ var BotService = class {
|
|
|
4454
4758
|
if (botId === "" || name === "" || provider === void 0) throw new ArkmePluginError("bot-contract-invalid", "Bot 响应不完整", true, 502);
|
|
4455
4759
|
const rawStatus = stringValue$1(raw.status).trim();
|
|
4456
4760
|
const status = rawStatus === "online" || rawStatus === "offline" ? rawStatus : "unknown";
|
|
4761
|
+
const createdAtMillis = botPrivateChatTimestamp(raw.created_at ?? raw.createdAt);
|
|
4457
4762
|
return {
|
|
4458
4763
|
botRef: this.sealBotRef(userId, botId, provider),
|
|
4764
|
+
directoryKey: await this.botDirectoryKey(userId, botId),
|
|
4459
4765
|
name,
|
|
4460
4766
|
provider,
|
|
4461
4767
|
description: stringValue$1(raw.description).trim(),
|
|
4462
4768
|
status,
|
|
4463
4769
|
directChatAvailable: stringValue$1(raw.subject_uid).trim() !== "" || stringValue$1(raw.chat_session_uid).trim() !== "",
|
|
4770
|
+
...createdAtMillis === 0 ? {} : { createdAtMillis },
|
|
4464
4771
|
...this.botAvatarProjection(raw, userId, botId)
|
|
4465
4772
|
};
|
|
4466
4773
|
}
|
|
4774
|
+
async botManageProfileFromData(data, userId) {
|
|
4775
|
+
const raw = botProfileSource(data);
|
|
4776
|
+
const summary = await this.botSummaryFromData(raw, userId);
|
|
4777
|
+
const joinedGroups = listValue$20(data.joined_groups).map((value) => objectValue$1(value)).map((group) => ({
|
|
4778
|
+
title: stringValue$1(group.subject_title).trim() || stringValue$1(group.subject_uid).trim() || "未命名群聊",
|
|
4779
|
+
installedAtMillis: botPrivateChatTimestamp(group.installed_at)
|
|
4780
|
+
}));
|
|
4781
|
+
return {
|
|
4782
|
+
...summary,
|
|
4783
|
+
mentionEntryEnabled: raw.mention_entry_enabled !== false,
|
|
4784
|
+
tokenPreview: stringValue$1(raw.token_preview).trim(),
|
|
4785
|
+
canRevealToken: raw.can_reveal_token !== false,
|
|
4786
|
+
tokenRevealEnabled: data.token_reveal_enabled !== false,
|
|
4787
|
+
gatewayUrl: stringValue$1(data.gateway_url).trim(),
|
|
4788
|
+
webhookUrl: stringValue$1(data.webhook_url).trim(),
|
|
4789
|
+
recordCount: Math.max(-1, Math.trunc(numberValue$19(raw.record_count))),
|
|
4790
|
+
webhookSecurity: botWebhookSecurity(data.webhook_security ?? raw.webhook_security),
|
|
4791
|
+
joinedGroups
|
|
4792
|
+
};
|
|
4793
|
+
}
|
|
4467
4794
|
botAvatarProjection(raw, userId, botId) {
|
|
4468
4795
|
const sourceUrl = stringValue$1(raw.avatar_url ?? raw.avatarUrl).trim();
|
|
4469
4796
|
if (sourceUrl === "") return {};
|
|
@@ -4544,6 +4871,9 @@ var BotService = class {
|
|
|
4544
4871
|
this.pruneBotRefs();
|
|
4545
4872
|
return botRef;
|
|
4546
4873
|
}
|
|
4874
|
+
async botDirectoryKey(userId, botId) {
|
|
4875
|
+
return `arkme-bot-directory-v1.${createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(`arkme-bot-directory-v1:${String(userId)}:${botId}`).digest("base64url")}`;
|
|
4876
|
+
}
|
|
4547
4877
|
async openBotRef(botRef, expectedUserId) {
|
|
4548
4878
|
const normalized = botRef.trim();
|
|
4549
4879
|
if (!BOT_REF_PATTERN.test(normalized)) throw new ArkmePluginError("bot-ref-invalid", "Bot 引用无效", false);
|
|
@@ -15873,6 +16203,9 @@ var ArkmeService = class {
|
|
|
15873
16203
|
async listBots(options = {}) {
|
|
15874
16204
|
return await this.bot.listBots(options);
|
|
15875
16205
|
}
|
|
16206
|
+
async listBotPrivateChatDirectory(options = {}) {
|
|
16207
|
+
return await this.bot.listBotPrivateChatDirectory(options);
|
|
16208
|
+
}
|
|
15876
16209
|
async createBot(input, options = {}) {
|
|
15877
16210
|
return await this.bot.createBot(input, options);
|
|
15878
16211
|
}
|
|
@@ -15882,9 +16215,33 @@ var ArkmeService = class {
|
|
|
15882
16215
|
async revealBotSecret(botRef, options = {}) {
|
|
15883
16216
|
return await this.bot.revealBotSecret(botRef, options);
|
|
15884
16217
|
}
|
|
16218
|
+
async manageBotProfile(botRef, options = {}) {
|
|
16219
|
+
return await this.bot.manageBotProfile(botRef, options);
|
|
16220
|
+
}
|
|
16221
|
+
async updateManagedBot(botRef, input, options = {}) {
|
|
16222
|
+
return await this.bot.updateManagedBot(botRef, input, options);
|
|
16223
|
+
}
|
|
16224
|
+
async revealManagedBotToken(botRef, options = {}) {
|
|
16225
|
+
return await this.bot.revealManagedBotToken(botRef, options);
|
|
16226
|
+
}
|
|
16227
|
+
async deleteManagedBot(botRef, confirmationName, options = {}) {
|
|
16228
|
+
await this.bot.deleteManagedBot(botRef, confirmationName, options);
|
|
16229
|
+
}
|
|
16230
|
+
async botNotificationPreference(botRef, options = {}) {
|
|
16231
|
+
return await this.bot.botNotificationPreference(botRef, options);
|
|
16232
|
+
}
|
|
16233
|
+
async updateBotNotificationPreference(botRef, muted, options = {}) {
|
|
16234
|
+
return await this.bot.updateBotNotificationPreference(botRef, muted, options);
|
|
16235
|
+
}
|
|
15885
16236
|
async openBotChat(botRef, options = {}) {
|
|
15886
16237
|
return await this.bot.openBotChat(botRef, options);
|
|
15887
16238
|
}
|
|
16239
|
+
async openBotPrivateChat(botRef, options = {}) {
|
|
16240
|
+
return await this.bot.openBotPrivateChat(botRef, options);
|
|
16241
|
+
}
|
|
16242
|
+
async sendBotPrivateChatMessage(botRef, content, options = {}) {
|
|
16243
|
+
return await this.bot.sendBotPrivateChatMessage(botRef, content, options);
|
|
16244
|
+
}
|
|
15888
16245
|
async listGroupBots(groupSourceRef, options = {}) {
|
|
15889
16246
|
return await this.bot.listGroupBots(groupSourceRef, options);
|
|
15890
16247
|
}
|
|
@@ -16179,6 +16536,9 @@ var ArkmeService = class {
|
|
|
16179
16536
|
async listSources(directory, options = {}) {
|
|
16180
16537
|
return await this.source.listSources(directory, options);
|
|
16181
16538
|
}
|
|
16539
|
+
async setChatDirectoryPolicy(sourceRef, options = {}) {
|
|
16540
|
+
return await this.source.setChatDirectoryPolicy(sourceRef, options);
|
|
16541
|
+
}
|
|
16182
16542
|
async dshBetaCommunityEntryState(signal) {
|
|
16183
16543
|
return await this.community.dshBetaCommunityEntryState(signal);
|
|
16184
16544
|
}
|