@senguoyun/dsh-arkme 0.1.33 → 0.1.35
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 +1 -1
- package/docs/plugin-release.md +14 -1
- package/lib/client.js +36141 -32483
- package/lib/client.js.map +1 -1
- package/lib/index.js +162 -16
- package/lib/persistent-extension.js +1 -1
- package/lib/{persistent-runtime-DUqdJv8K.js → persistent-runtime-e4gV6dqq.js} +1775 -710
- package/lib/sdk.js +19 -0
- package/lib/types/arkme-service.d.ts +13 -1
- package/lib/types/arkme-service.d.ts.map +1 -1
- package/lib/types/billing-gateway.d.ts.map +1 -1
- package/lib/types/client/ArkmeAvatar.d.ts +16 -10
- package/lib/types/client/ArkmeAvatar.d.ts.map +1 -1
- package/lib/types/client/ArkmeBillingSettings.d.ts +4 -0
- package/lib/types/client/ArkmeBillingSettings.d.ts.map +1 -1
- package/lib/types/client/ArkmeCalendarSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeCallHistorySurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeCallSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeChatMemberActions.d.ts +4 -3
- package/lib/types/client/ArkmeChatMemberActions.d.ts.map +1 -1
- package/lib/types/client/ArkmeExtensionReviews.d.ts +2 -1
- package/lib/types/client/ArkmeExtensionReviews.d.ts.map +1 -1
- package/lib/types/client/ArkmeGroupChatControls.d.ts.map +1 -1
- package/lib/types/client/ArkmeMarketplace.d.ts +4 -2
- package/lib/types/client/ArkmeMarketplace.d.ts.map +1 -1
- package/lib/types/client/ArkmeMessageReportDialog.d.ts +8 -0
- package/lib/types/client/ArkmeMessageReportDialog.d.ts.map +1 -0
- package/lib/types/client/ArkmeMessageSnapshotDialog.d.ts +17 -0
- package/lib/types/client/ArkmeMessageSnapshotDialog.d.ts.map +1 -0
- package/lib/types/client/ArkmeNoteDetails.d.ts.map +1 -1
- package/lib/types/client/ArkmeOutgoingCallHost.d.ts.map +1 -1
- package/lib/types/client/ArkmePersistentShell.d.ts.map +1 -1
- package/lib/types/client/ArkmeRelatedQuickNotes.d.ts +47 -0
- package/lib/types/client/ArkmeRelatedQuickNotes.d.ts.map +1 -0
- package/lib/types/client/ArkmeRichComposerInput.d.ts +3 -1
- package/lib/types/client/ArkmeRichComposerInput.d.ts.map +1 -1
- package/lib/types/client/ArkmeSearchSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeSettingsSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeSidebar.d.ts +7 -4
- package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
- package/lib/types/client/ArkmeVirtualWorkspace.d.ts.map +1 -1
- package/lib/types/client/ArkmeWorldSurface.d.ts +6 -1
- package/lib/types/client/ArkmeWorldSurface.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/arkme-billing.d.ts +7 -1
- package/lib/types/client/arkme-billing.d.ts.map +1 -1
- package/lib/types/client/avatar-image-runtime.d.ts +3 -0
- package/lib/types/client/avatar-image-runtime.d.ts.map +1 -0
- package/lib/types/client/avatar-image-store.d.ts +44 -0
- package/lib/types/client/avatar-image-store.d.ts.map +1 -0
- package/lib/types/client/calendar-invalidation-store.d.ts +26 -0
- package/lib/types/client/calendar-invalidation-store.d.ts.map +1 -0
- package/lib/types/client/chat-directory-store.d.ts +23 -13
- package/lib/types/client/chat-directory-store.d.ts.map +1 -1
- package/lib/types/client/composer-draft-store.d.ts +3 -3
- package/lib/types/client/composer-draft-store.d.ts.map +1 -1
- package/lib/types/client/composer-placeholder.d.ts +13 -0
- package/lib/types/client/composer-placeholder.d.ts.map +1 -0
- package/lib/types/client/conversation-memory-cache.d.ts +11 -14
- package/lib/types/client/conversation-memory-cache.d.ts.map +1 -1
- package/lib/types/client/file-send-tasks.d.ts +3 -1
- package/lib/types/client/file-send-tasks.d.ts.map +1 -1
- package/lib/types/client/interwoven-moments.d.ts +13 -2
- package/lib/types/client/interwoven-moments.d.ts.map +1 -1
- package/lib/types/client/navigation-cache.d.ts.map +1 -1
- package/lib/types/client/presentation-maintenance-runtime.d.ts +13 -0
- package/lib/types/client/presentation-maintenance-runtime.d.ts.map +1 -0
- package/lib/types/client/provider-instance-runtime.d.ts +5 -2
- package/lib/types/client/provider-instance-runtime.d.ts.map +1 -1
- package/lib/types/client/realtime-client-events.d.ts +6 -0
- package/lib/types/client/realtime-client-events.d.ts.map +1 -1
- package/lib/types/client/record-capture-location.d.ts +8 -0
- package/lib/types/client/record-capture-location.d.ts.map +1 -0
- package/lib/types/client/redesign/contacts/contacts-tab-store.d.ts.map +1 -1
- package/lib/types/client/related-recordings.d.ts +1 -1
- package/lib/types/client/source-identity.d.ts +5 -0
- package/lib/types/client/source-identity.d.ts.map +1 -0
- package/lib/types/client/ui-controller.d.ts +6 -0
- package/lib/types/client/ui-controller.d.ts.map +1 -1
- package/lib/types/client/use-arkme-avatar-image.d.ts +3 -0
- package/lib/types/client/use-arkme-avatar-image.d.ts.map +1 -0
- package/lib/types/extensions/manager.d.ts.map +1 -1
- package/lib/types/extensions/types.d.ts +1 -0
- package/lib/types/extensions/types.d.ts.map +1 -1
- package/lib/types/host-api.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/local-database.d.ts +1 -0
- package/lib/types/local-database.d.ts.map +1 -1
- package/lib/types/request-coordinator.d.ts.map +1 -1
- package/lib/types/sdk/index.d.ts +7 -2
- package/lib/types/sdk/index.d.ts.map +1 -1
- package/lib/types/services/chat-realtime-service.d.ts.map +1 -1
- package/lib/types/services/chat-service.d.ts +21 -2
- package/lib/types/services/chat-service.d.ts.map +1 -1
- package/lib/types/services/group-ai-polish-service.d.ts +3 -1
- package/lib/types/services/group-ai-polish-service.d.ts.map +1 -1
- package/lib/types/services/interwoven-service.d.ts +3 -0
- package/lib/types/services/interwoven-service.d.ts.map +1 -1
- package/lib/types/services/record-service.d.ts +10 -3
- package/lib/types/services/record-service.d.ts.map +1 -1
- package/lib/types/services/related-quick-note-service.d.ts +38 -0
- package/lib/types/services/related-quick-note-service.d.ts.map +1 -0
- package/lib/types/services/world-service.d.ts.map +1 -1
- package/lib/types/state-store.d.ts.map +1 -1
- package/lib/types/types.d.ts +111 -5
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -525,6 +525,7 @@ var ArkmeRequestCoordinator = class {
|
|
|
525
525
|
this.bump(request, "staleDropped");
|
|
526
526
|
throw new ArkmeStaleRequestError();
|
|
527
527
|
}
|
|
528
|
+
if (this.inFlight.get(fullKey)?.promise !== promise) return value;
|
|
528
529
|
this.failures.delete(fullKey);
|
|
529
530
|
if (cacheMs > 0) this.cache.set(fullKey, {
|
|
530
531
|
value: clone(value),
|
|
@@ -533,7 +534,7 @@ var ArkmeRequestCoordinator = class {
|
|
|
533
534
|
});
|
|
534
535
|
return value;
|
|
535
536
|
}).catch((error) => {
|
|
536
|
-
if (this.epoch(scope) === epoch && failureCooldownMs > 0 && (request.shouldCooldown?.(error) ?? true)) {
|
|
537
|
+
if (this.epoch(scope) === epoch && this.inFlight.get(fullKey)?.promise === promise && failureCooldownMs > 0 && (request.shouldCooldown?.(error) ?? true)) {
|
|
537
538
|
const jitter = .9 + this.random() * .2;
|
|
538
539
|
this.failures.set(fullKey, {
|
|
539
540
|
error,
|
|
@@ -570,6 +571,7 @@ var ArkmeRequestCoordinator = class {
|
|
|
570
571
|
const prefix = `${scopeInput.trim() || "public"}\u0000${keyPrefix}`;
|
|
571
572
|
for (const key of this.cache.keys()) if (key.startsWith(prefix)) this.cache.delete(key);
|
|
572
573
|
for (const key of this.failures.keys()) if (key.startsWith(prefix)) this.failures.delete(key);
|
|
574
|
+
for (const key of this.inFlight.keys()) if (key.startsWith(prefix)) this.inFlight.delete(key);
|
|
573
575
|
}
|
|
574
576
|
snapshotStats() {
|
|
575
577
|
return Object.fromEntries([...this.stats].map(([key, value]) => [key, { ...value }]));
|
|
@@ -1469,7 +1471,7 @@ var HttpArkmeBillingGateway = class {
|
|
|
1469
1471
|
return new ArkmePluginError(error.code, error.message, retryable, error.httpStatus, { cause: error });
|
|
1470
1472
|
}
|
|
1471
1473
|
async quota(signal) {
|
|
1472
|
-
const data = objectValue$1(await this.post("intelligent", "/api/v1/managed-ai/balance/query", {}, "interactive-read", signal
|
|
1474
|
+
const data = objectValue$1(await this.post("intelligent", "/api/v1/managed-ai/balance/query", {}, "interactive-read", signal));
|
|
1473
1475
|
const currency = stringValue$1(data.currency).trim();
|
|
1474
1476
|
if (currency !== "CNY") throw new ArkmePluginError("billing-contract-invalid", "余额接口币种无效", true, 502);
|
|
1475
1477
|
const availableNanoCny = nanoCny(data.available_nano_cny, "available_nano_cny");
|
|
@@ -1843,13 +1845,13 @@ function bestMatchingCategory(text) {
|
|
|
1843
1845
|
}
|
|
1844
1846
|
//#endregion
|
|
1845
1847
|
//#region src/services/ai-video-service.ts
|
|
1846
|
-
function numberValue$
|
|
1848
|
+
function numberValue$26(value) {
|
|
1847
1849
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
1848
1850
|
}
|
|
1849
1851
|
function booleanValue$15(value) {
|
|
1850
1852
|
return value === true;
|
|
1851
1853
|
}
|
|
1852
|
-
function listValue$
|
|
1854
|
+
function listValue$27(value) {
|
|
1853
1855
|
return Array.isArray(value) ? value : [];
|
|
1854
1856
|
}
|
|
1855
1857
|
var AiVideoService = class {
|
|
@@ -1863,9 +1865,9 @@ var AiVideoService = class {
|
|
|
1863
1865
|
return {
|
|
1864
1866
|
allowed: booleanValue$15(data.allowed),
|
|
1865
1867
|
message: stringValue$1(data.message).trim() || "AI 视频内容检查已完成",
|
|
1866
|
-
selectedDurationMillis: Math.max(0, numberValue$
|
|
1867
|
-
minimumDurationMillis: Math.max(0, numberValue$
|
|
1868
|
-
selectedSegmentCount: Math.max(0, numberValue$
|
|
1868
|
+
selectedDurationMillis: Math.max(0, numberValue$26(data.selected_duration_millis)),
|
|
1869
|
+
minimumDurationMillis: Math.max(0, numberValue$26(data.minimum_duration_millis)),
|
|
1870
|
+
selectedSegmentCount: Math.max(0, numberValue$26(data.selected_segment_count)),
|
|
1869
1871
|
retryable: booleanValue$15(data.retryable),
|
|
1870
1872
|
...stringValue$1(data.reason_code).trim() === "" ? {} : { reasonCode: stringValue$1(data.reason_code).trim() },
|
|
1871
1873
|
...stringValue$1(data.proof).trim() === "" ? {} : { proof: stringValue$1(data.proof).trim() }
|
|
@@ -1901,7 +1903,7 @@ var AiVideoService = class {
|
|
|
1901
1903
|
...options.statuses === void 0 || options.statuses.length === 0 ? {} : { statuses: options.statuses }
|
|
1902
1904
|
}, session, options.signal);
|
|
1903
1905
|
return {
|
|
1904
|
-
items: listValue$
|
|
1906
|
+
items: listValue$27(data.items).map((raw) => this.aiVideoListItem(raw)).filter((item) => item !== void 0),
|
|
1905
1907
|
hasMore: booleanValue$15(data.has_more),
|
|
1906
1908
|
...stringValue$1(data.next_cursor).trim() === "" ? {} : { nextCursor: stringValue$1(data.next_cursor).trim() }
|
|
1907
1909
|
};
|
|
@@ -1915,10 +1917,10 @@ var AiVideoService = class {
|
|
|
1915
1917
|
return {
|
|
1916
1918
|
allowed: booleanValue$15(data.allowed),
|
|
1917
1919
|
message: stringValue$1(data.message).trim() || "AI 视频内容检查已完成",
|
|
1918
|
-
selectedDurationMillis: Math.max(0, numberValue$
|
|
1919
|
-
minimumDurationMillis: Math.max(0, numberValue$
|
|
1920
|
-
selectedSegmentCount: Math.max(0, numberValue$
|
|
1921
|
-
selectedTextCount: Math.max(0, numberValue$
|
|
1920
|
+
selectedDurationMillis: Math.max(0, numberValue$26(data.selected_duration_millis)),
|
|
1921
|
+
minimumDurationMillis: Math.max(0, numberValue$26(data.minimum_duration_millis)),
|
|
1922
|
+
selectedSegmentCount: Math.max(0, numberValue$26(data.selected_segment_count)),
|
|
1923
|
+
selectedTextCount: Math.max(0, numberValue$26(data.selected_text_count)),
|
|
1922
1924
|
retryable: booleanValue$15(data.retryable),
|
|
1923
1925
|
...stringValue$1(data.reason_code).trim() === "" ? {} : { reasonCode: stringValue$1(data.reason_code).trim() },
|
|
1924
1926
|
...stringValue$1(data.proof).trim() === "" ? {} : { proof: stringValue$1(data.proof).trim() }
|
|
@@ -1958,19 +1960,19 @@ var AiVideoService = class {
|
|
|
1958
1960
|
"canceled"
|
|
1959
1961
|
])).has(status)) throw new ArkmePluginError("ai-video-contract-invalid", "AI 视频服务返回了无效任务信息", true, 502);
|
|
1960
1962
|
const selection = objectValue$1(data.selection);
|
|
1961
|
-
const segmentCount = listValue$
|
|
1962
|
-
const textCount = listValue$
|
|
1963
|
+
const segmentCount = listValue$27(selection.segments).length;
|
|
1964
|
+
const textCount = listValue$27(selection.texts).length;
|
|
1963
1965
|
return {
|
|
1964
1966
|
jobId,
|
|
1965
1967
|
status,
|
|
1966
1968
|
stage: stringValue$1(data.stage).trim() || status,
|
|
1967
|
-
progress: Math.min(100, Math.max(0, Math.trunc(numberValue$
|
|
1969
|
+
progress: Math.min(100, Math.max(0, Math.trunc(numberValue$26(data.progress)))),
|
|
1968
1970
|
selectedSegmentCount: segmentCount,
|
|
1969
1971
|
...textCount === 0 ? {} : { selectedTextCount: textCount },
|
|
1970
1972
|
retryable: booleanValue$15(data.retryable),
|
|
1971
1973
|
...stringValue$1(data.video_asset_uid).trim() === "" ? {} : { videoAssetUid: stringValue$1(data.video_asset_uid).trim() },
|
|
1972
1974
|
...stringValue$1(data.cover_asset_uid).trim() === "" ? {} : { coverAssetUid: stringValue$1(data.cover_asset_uid).trim() },
|
|
1973
|
-
...numberValue$
|
|
1975
|
+
...numberValue$26(data.video_duration_millis) <= 0 ? {} : { videoDurationMillis: numberValue$26(data.video_duration_millis) },
|
|
1974
1976
|
...stringValue$1(data.error_code).trim() === "" ? {} : { errorCode: stringValue$1(data.error_code).trim() },
|
|
1975
1977
|
...stringValue$1(data.error_message).trim() === "" ? {} : { errorMessage: stringValue$1(data.error_message).trim() },
|
|
1976
1978
|
...stringValue$1(data.failure_stage).trim() === "" ? {} : { failureStage: stringValue$1(data.failure_stage).trim() }
|
|
@@ -1993,17 +1995,17 @@ var AiVideoService = class {
|
|
|
1993
1995
|
sessionId: stringValue$1(item.session_id).trim(),
|
|
1994
1996
|
status,
|
|
1995
1997
|
stage: stringValue$1(item.stage).trim() || status,
|
|
1996
|
-
progress: Math.min(100, Math.max(0, Math.trunc(numberValue$
|
|
1998
|
+
progress: Math.min(100, Math.max(0, Math.trunc(numberValue$26(item.progress)))),
|
|
1997
1999
|
title: stringValue$1(source.title).trim() || "长录音 AI 视频",
|
|
1998
|
-
sourceStartedAtMillis: numberValue$
|
|
1999
|
-
selectedDurationMillis: Math.max(0, numberValue$
|
|
2000
|
-
selectedSegmentCount: Math.max(0, Math.trunc(numberValue$
|
|
2000
|
+
sourceStartedAtMillis: numberValue$26(source.started_at),
|
|
2001
|
+
selectedDurationMillis: Math.max(0, numberValue$26(source.selected_duration_millis)),
|
|
2002
|
+
selectedSegmentCount: Math.max(0, Math.trunc(numberValue$26(item.selected_segment_count))),
|
|
2001
2003
|
retryable: booleanValue$15(item.retryable),
|
|
2002
|
-
createdAtMillis: numberValue$
|
|
2003
|
-
updatedAtMillis: numberValue$
|
|
2004
|
+
createdAtMillis: numberValue$26(item.created_at),
|
|
2005
|
+
updatedAtMillis: numberValue$26(item.updated_at),
|
|
2004
2006
|
...stringValue$1(item.cover_asset_uid).trim() === "" ? {} : { coverAssetUid: stringValue$1(item.cover_asset_uid).trim() },
|
|
2005
2007
|
...stringValue$1(item.video_asset_uid).trim() === "" ? {} : { videoAssetUid: stringValue$1(item.video_asset_uid).trim() },
|
|
2006
|
-
...numberValue$
|
|
2008
|
+
...numberValue$26(item.video_duration_millis) <= 0 ? {} : { videoDurationMillis: numberValue$26(item.video_duration_millis) },
|
|
2007
2009
|
...stringValue$1(item.error_code).trim() === "" ? {} : { errorCode: stringValue$1(item.error_code).trim() },
|
|
2008
2010
|
...stringValue$1(item.error_message).trim() === "" ? {} : { errorMessage: clippedText(item.error_message, 500) }
|
|
2009
2011
|
};
|
|
@@ -2029,13 +2031,13 @@ const ARKO_RUN_STATUSES = /* @__PURE__ */ new Set([
|
|
|
2029
2031
|
"expired"
|
|
2030
2032
|
]);
|
|
2031
2033
|
const ARKO_PROFILE_DISPLAY_NAME_CACHE_TTL_MS = 10 * 6e4;
|
|
2032
|
-
function numberValue$
|
|
2034
|
+
function numberValue$25(value) {
|
|
2033
2035
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2034
2036
|
}
|
|
2035
2037
|
function booleanValue$14(value) {
|
|
2036
2038
|
return value === true;
|
|
2037
2039
|
}
|
|
2038
|
-
function listValue$
|
|
2040
|
+
function listValue$26(value) {
|
|
2039
2041
|
return Array.isArray(value) ? value : [];
|
|
2040
2042
|
}
|
|
2041
2043
|
function optionalString$3(value) {
|
|
@@ -2064,7 +2066,7 @@ function joinUrlWithQuery(baseUrl, path, query) {
|
|
|
2064
2066
|
}
|
|
2065
2067
|
function arkoProfileFromData(data) {
|
|
2066
2068
|
const displayName = stringValue$1(data.display_name).trim();
|
|
2067
|
-
const version = numberValue$
|
|
2069
|
+
const version = numberValue$25(data.version);
|
|
2068
2070
|
if (displayName === "" || !Number.isSafeInteger(version) || version < 0) throw new ArkmePluginError("arko-profile-contract-invalid", "Arko 资料响应不完整", true, 502);
|
|
2069
2071
|
return {
|
|
2070
2072
|
displayName,
|
|
@@ -2096,7 +2098,7 @@ function arkoModelCatalogFromData(data) {
|
|
|
2096
2098
|
const defaultRouteKey = arkoModelRouteKey(data.default_route_key);
|
|
2097
2099
|
const effectiveRouteKey = arkoModelRouteKey(data.effective_route_key);
|
|
2098
2100
|
const selectionSource = stringValue$1(data.selection_source);
|
|
2099
|
-
const options = listValue$
|
|
2101
|
+
const options = listValue$26(data.items).map(arkoModelOptionFromData);
|
|
2100
2102
|
const routeKeys = new Set(options.map((option) => option.routeKey));
|
|
2101
2103
|
const selected = options.filter((option) => option.selected);
|
|
2102
2104
|
if (selectionSource !== "default" && selectionSource !== "personal" || options.length === 0 || options.length > 16 || routeKeys.size !== options.length || !routeKeys.has(defaultRouteKey) || !routeKeys.has(effectiveRouteKey) || selected.length !== 1 || selected[0]?.routeKey !== effectiveRouteKey) throw new ArkmePluginError("arko-model-contract-invalid", "Arko 模型目录响应无效", true, 502);
|
|
@@ -2117,9 +2119,9 @@ function parsedJsonRecord(value) {
|
|
|
2117
2119
|
}
|
|
2118
2120
|
function arkoHistoryItemFromData(value) {
|
|
2119
2121
|
const data = objectValue$1(value);
|
|
2120
|
-
const messageId = numberValue$
|
|
2121
|
-
const sessionId = numberValue$
|
|
2122
|
-
const roleCode = numberValue$
|
|
2122
|
+
const messageId = numberValue$25(data.id ?? data.msg_id ?? data.msgId);
|
|
2123
|
+
const sessionId = numberValue$25(data.session_id ?? data.sessionId);
|
|
2124
|
+
const roleCode = numberValue$25(data.role ?? data.sender_role ?? data.senderRole);
|
|
2123
2125
|
if (!Number.isSafeInteger(messageId) || messageId <= 0 || !Number.isSafeInteger(sessionId) || sessionId <= 0 || roleCode !== 2 && roleCode !== 3) return void 0;
|
|
2124
2126
|
const extra = parsedJsonRecord(data.extra ?? data.metadata ?? data.meta);
|
|
2125
2127
|
const extraData = parsedJsonRecord(extra.data);
|
|
@@ -2140,7 +2142,7 @@ function arkoHistoryItemFromData(value) {
|
|
|
2140
2142
|
extraData.updateAt,
|
|
2141
2143
|
data.updated_at,
|
|
2142
2144
|
data.updatedAt
|
|
2143
|
-
].map(numberValue$
|
|
2145
|
+
].map(numberValue$25).find((candidate) => candidate > 0) ?? 0;
|
|
2144
2146
|
const runUid = optionalString$3(extra.agent_run_uid);
|
|
2145
2147
|
const runStatus = optionalString$3(extra.agent_run_status);
|
|
2146
2148
|
const retryable = optionalBooleanValue$1(extra.agent_run_retryable);
|
|
@@ -2153,7 +2155,7 @@ function arkoHistoryItemFromData(value) {
|
|
|
2153
2155
|
text: stringValue$1(data.content ?? data.text_content ?? data.textContent),
|
|
2154
2156
|
reasoning: stringValue$1(data.reason_content ?? data.reason_text ?? data.reasonText),
|
|
2155
2157
|
createdAtMillis: activityAt > 0 && activityAt < 1e11 ? activityAt * 1e3 : activityAt,
|
|
2156
|
-
status: numberValue$
|
|
2158
|
+
status: numberValue$25(data.status ?? data.msg_status),
|
|
2157
2159
|
...runUid === void 0 ? {} : { runUid },
|
|
2158
2160
|
...runStatus === void 0 ? {} : { runStatus },
|
|
2159
2161
|
...retryable === void 0 ? {} : { retryable },
|
|
@@ -2179,7 +2181,7 @@ function arkoRunProjectionFromData(data) {
|
|
|
2179
2181
|
};
|
|
2180
2182
|
}
|
|
2181
2183
|
function arkoCreatedRecordUids(value) {
|
|
2182
|
-
return listValue$
|
|
2184
|
+
return listValue$26(value).map((item) => stringValue$1(item).trim()).filter((item) => item !== "");
|
|
2183
2185
|
}
|
|
2184
2186
|
function arkoStreamFrame(raw) {
|
|
2185
2187
|
try {
|
|
@@ -2208,7 +2210,7 @@ var ArkoService = class {
|
|
|
2208
2210
|
async arkoEnsureSession(signal) {
|
|
2209
2211
|
const session = await this.runtime.requireSession();
|
|
2210
2212
|
const latest = await this.runtime.authenticatedIntelligentPost("/api/v1/qa/latest-session", { type: ARKO_AGENT_DIRECT_SESSION_TYPE }, session, signal);
|
|
2211
|
-
const latestSessionId = numberValue$
|
|
2213
|
+
const latestSessionId = numberValue$25(latest.id);
|
|
2212
2214
|
if (Number.isSafeInteger(latestSessionId) && latestSessionId > 0) return {
|
|
2213
2215
|
sessionId: latestSessionId,
|
|
2214
2216
|
created: false,
|
|
@@ -2218,7 +2220,7 @@ var ArkoService = class {
|
|
|
2218
2220
|
}
|
|
2219
2221
|
async arkoCreateSession(signal) {
|
|
2220
2222
|
const session = await this.runtime.requireSession();
|
|
2221
|
-
const createdSessionId = numberValue$
|
|
2223
|
+
const createdSessionId = numberValue$25((await this.runtime.authenticatedIntelligentPost("/api/v1/qa/new-session", {
|
|
2222
2224
|
name: ARKO_DEFAULT_SESSION_NAME,
|
|
2223
2225
|
type: ARKO_AGENT_DIRECT_SESSION_TYPE
|
|
2224
2226
|
}, session, signal)).session_id);
|
|
@@ -2243,7 +2245,7 @@ var ArkoService = class {
|
|
|
2243
2245
|
const normalizedLimit = Math.min(ARKO_HISTORY_PAGE_LIMIT, Math.max(1, Math.trunc(limit)));
|
|
2244
2246
|
const normalizedOffset = Math.max(0, Math.trunc(offset));
|
|
2245
2247
|
const session = await this.runtime.requireSession();
|
|
2246
|
-
const rawItems = listValue$
|
|
2248
|
+
const rawItems = listValue$26((await this.runtime.authenticatedIntelligentPost("/api/v1/qa/message-list", {
|
|
2247
2249
|
limit: normalizedLimit,
|
|
2248
2250
|
offset: normalizedOffset,
|
|
2249
2251
|
session_type: ARKO_AGENT_DIRECT_SESSION_TYPE
|
|
@@ -2286,9 +2288,9 @@ var ArkoService = class {
|
|
|
2286
2288
|
};
|
|
2287
2289
|
if (modelRouteKey !== "") body.model_route_key = modelRouteKey;
|
|
2288
2290
|
const accepted = await this.runtime.authenticatedIntelligentPost("/api/v1/qa/new-msg-v2", body, session, options.signal);
|
|
2289
|
-
const userMsgId = numberValue$
|
|
2290
|
-
const assistantMsgId = numberValue$
|
|
2291
|
-
const acceptedSessionId = numberValue$
|
|
2291
|
+
const userMsgId = numberValue$25(accepted.user_msg_id);
|
|
2292
|
+
const assistantMsgId = numberValue$25(accepted.assistant_msg_id);
|
|
2293
|
+
const acceptedSessionId = numberValue$25(accepted.session_id) || sessionId;
|
|
2292
2294
|
if (!Number.isSafeInteger(acceptedSessionId) || acceptedSessionId <= 0 || !Number.isSafeInteger(userMsgId) || userMsgId <= 0 || !Number.isSafeInteger(assistantMsgId) || assistantMsgId <= 0) throw new ArkmePluginError("arko-ask-contract-invalid", "Arko 消息响应不完整", true, 502);
|
|
2293
2295
|
const runUid = stringValue$1(accepted.run_uid).trim();
|
|
2294
2296
|
if (runUid === "") throw new ArkmePluginError("arko-ask-contract-invalid", "Arko 消息响应缺少运行标识", true, 502);
|
|
@@ -2324,8 +2326,8 @@ var ArkoService = class {
|
|
|
2324
2326
|
}, session, signal);
|
|
2325
2327
|
const status = stringValue$1(data.status).trim();
|
|
2326
2328
|
const normalizedRunUid = stringValue$1(data.run_uid).trim() || runUid.trim();
|
|
2327
|
-
const sequence = numberValue$
|
|
2328
|
-
const surfaceAssistantMsgId = numberValue$
|
|
2329
|
+
const sequence = numberValue$25(data.sequence);
|
|
2330
|
+
const surfaceAssistantMsgId = numberValue$25(data.surface_assistant_msg_id);
|
|
2329
2331
|
const clientAction = optionalRecord(data.client_action);
|
|
2330
2332
|
if (normalizedRunUid !== runUid.trim() || !ARKO_RUN_STATUSES.has(status) || !Number.isSafeInteger(sequence) || sequence < 0 || !Number.isSafeInteger(surfaceAssistantMsgId) || surfaceAssistantMsgId <= 0) throw new ArkmePluginError("arko-run-status-contract-invalid", "Arko 运行状态响应不完整", true, 502);
|
|
2331
2333
|
return {
|
|
@@ -2563,13 +2565,13 @@ const ARKME_ARRANGEMENT_REF_TTL_MILLIS = 900 * 1e3;
|
|
|
2563
2565
|
const MAX_ARKME_ARRANGEMENT_REFS = 4096;
|
|
2564
2566
|
const ARKME_ARRANGEMENT_REMINDER_REF_TTL_MILLIS = 900 * 1e3;
|
|
2565
2567
|
const MAX_ARKME_ARRANGEMENT_REMINDER_REFS = 4096;
|
|
2566
|
-
function numberValue$
|
|
2568
|
+
function numberValue$24(value) {
|
|
2567
2569
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2568
2570
|
}
|
|
2569
2571
|
function booleanValue$13(value) {
|
|
2570
2572
|
return value === true;
|
|
2571
2573
|
}
|
|
2572
|
-
function listValue$
|
|
2574
|
+
function listValue$25(value) {
|
|
2573
2575
|
return Array.isArray(value) ? value : [];
|
|
2574
2576
|
}
|
|
2575
2577
|
function arrangementStatusCode(status) {
|
|
@@ -2579,7 +2581,7 @@ function arrangementStatusCode(status) {
|
|
|
2579
2581
|
return -1;
|
|
2580
2582
|
}
|
|
2581
2583
|
function arrangementStatus(value) {
|
|
2582
|
-
const code = Math.trunc(numberValue$
|
|
2584
|
+
const code = Math.trunc(numberValue$24(value));
|
|
2583
2585
|
if (code === 1) return "identified";
|
|
2584
2586
|
if (code === 2) return "following";
|
|
2585
2587
|
if (code === 3) return "completed";
|
|
@@ -2628,9 +2630,9 @@ var ArrangementService = class {
|
|
|
2628
2630
|
limit,
|
|
2629
2631
|
offset
|
|
2630
2632
|
}, session, options.signal, { lane: "interactive-read" });
|
|
2631
|
-
const rawItems = listValue$
|
|
2633
|
+
const rawItems = listValue$25(data.list);
|
|
2632
2634
|
const items = await Promise.all(rawItems.map(async (raw) => await this.arrangementItem(raw, session.userId)));
|
|
2633
|
-
const total = Math.max(0, Math.trunc(numberValue$
|
|
2635
|
+
const total = Math.max(0, Math.trunc(numberValue$24(data.total)));
|
|
2634
2636
|
const nextOffset = offset + rawItems.length;
|
|
2635
2637
|
const hasMore = rawItems.length > 0 && nextOffset < total;
|
|
2636
2638
|
return {
|
|
@@ -2654,9 +2656,9 @@ var ArrangementService = class {
|
|
|
2654
2656
|
offset,
|
|
2655
2657
|
unread_only: options.unreadOnly === true
|
|
2656
2658
|
}, session, options.signal, { lane: "interactive-read" });
|
|
2657
|
-
const rawItems = listValue$
|
|
2659
|
+
const rawItems = listValue$25(data.list);
|
|
2658
2660
|
const items = await Promise.all(rawItems.map(async (raw) => await this.arrangementReminderEvent(raw, session.userId)));
|
|
2659
|
-
const total = Math.max(0, Math.trunc(numberValue$
|
|
2661
|
+
const total = Math.max(0, Math.trunc(numberValue$24(data.total)));
|
|
2660
2662
|
const nextOffset = offset + rawItems.length;
|
|
2661
2663
|
const hasMore = rawItems.length > 0 && nextOffset < total;
|
|
2662
2664
|
return {
|
|
@@ -2679,7 +2681,7 @@ var ArrangementService = class {
|
|
|
2679
2681
|
project(data.next_reminder)
|
|
2680
2682
|
]);
|
|
2681
2683
|
return {
|
|
2682
|
-
unreadCount: Math.max(0, Math.trunc(numberValue$
|
|
2684
|
+
unreadCount: Math.max(0, Math.trunc(numberValue$24(data.unread_count))),
|
|
2683
2685
|
...latestUnread === void 0 ? {} : { latestUnread },
|
|
2684
2686
|
...latestEvent === void 0 ? {} : { latestEvent },
|
|
2685
2687
|
...nextReminder === void 0 ? {} : { nextReminder }
|
|
@@ -2783,7 +2785,7 @@ var ArrangementService = class {
|
|
|
2783
2785
|
}, session, signal);
|
|
2784
2786
|
return {
|
|
2785
2787
|
outcome: "confirmed",
|
|
2786
|
-
updatedCount: Math.max(0, Math.trunc(numberValue$
|
|
2788
|
+
updatedCount: Math.max(0, Math.trunc(numberValue$24(data.updated_count)))
|
|
2787
2789
|
};
|
|
2788
2790
|
} catch (error) {
|
|
2789
2791
|
if (!isAmbiguousArrangementWriteError(error)) throw error;
|
|
@@ -2801,7 +2803,7 @@ var ArrangementService = class {
|
|
|
2801
2803
|
}, session, signal);
|
|
2802
2804
|
return {
|
|
2803
2805
|
outcome: "confirmed",
|
|
2804
|
-
updatedCount: Math.max(0, Math.trunc(numberValue$
|
|
2806
|
+
updatedCount: Math.max(0, Math.trunc(numberValue$24(data.updated_count)))
|
|
2805
2807
|
};
|
|
2806
2808
|
} catch (error) {
|
|
2807
2809
|
if (!isAmbiguousArrangementWriteError(error)) throw error;
|
|
@@ -2816,7 +2818,7 @@ var ArrangementService = class {
|
|
|
2816
2818
|
const data = await this.runtime.authenticatedIntelligentPost("/api/v1/arrangements/reminders/clear", {}, session, signal);
|
|
2817
2819
|
return {
|
|
2818
2820
|
outcome: "confirmed",
|
|
2819
|
-
updatedCount: Math.max(0, Math.trunc(numberValue$
|
|
2821
|
+
updatedCount: Math.max(0, Math.trunc(numberValue$24(data.updated_count)))
|
|
2820
2822
|
};
|
|
2821
2823
|
} catch (error) {
|
|
2822
2824
|
if (!isAmbiguousArrangementWriteError(error)) throw error;
|
|
@@ -2849,7 +2851,7 @@ var ArrangementService = class {
|
|
|
2849
2851
|
}
|
|
2850
2852
|
async reconcileArrangementDelete(arrangementRef, arrangementUid, session) {
|
|
2851
2853
|
try {
|
|
2852
|
-
const visible = listValue$
|
|
2854
|
+
const visible = listValue$25((await this.runtime.authenticatedIntelligentPost("/api/v1/arrangements/list", {
|
|
2853
2855
|
status: -1,
|
|
2854
2856
|
uids: [arrangementUid],
|
|
2855
2857
|
limit: 1,
|
|
@@ -2880,8 +2882,8 @@ var ArrangementService = class {
|
|
|
2880
2882
|
const item = objectValue$1(raw);
|
|
2881
2883
|
const arrangementUid = stringValue$1(item.uid).trim();
|
|
2882
2884
|
if (arrangementUid === "") throw new ArkmePluginError("arrangement-contract-invalid", "安排响应缺少业务身份", true, 502);
|
|
2883
|
-
const dueAtMillis = Math.trunc(numberValue$
|
|
2884
|
-
const remindAtMillis = Math.trunc(numberValue$
|
|
2885
|
+
const dueAtMillis = Math.trunc(numberValue$24(item.due_at));
|
|
2886
|
+
const remindAtMillis = Math.trunc(numberValue$24(item.remind_at));
|
|
2885
2887
|
return {
|
|
2886
2888
|
arrangementRef: await this.arrangementRef(viewerUserId, arrangementUid),
|
|
2887
2889
|
title: stringValue$1(item.title),
|
|
@@ -2889,8 +2891,8 @@ var ArrangementService = class {
|
|
|
2889
2891
|
status: arrangementStatus(item.status),
|
|
2890
2892
|
reminderEnabled: booleanValue$13(item.reminder_enabled),
|
|
2891
2893
|
reminderState: stringValue$1(item.reminder_state),
|
|
2892
|
-
createdAtMillis: Math.trunc(numberValue$
|
|
2893
|
-
updatedAtMillis: Math.trunc(numberValue$
|
|
2894
|
+
createdAtMillis: Math.trunc(numberValue$24(item.create_at)),
|
|
2895
|
+
updatedAtMillis: Math.trunc(numberValue$24(item.update_at)),
|
|
2894
2896
|
...dueAtMillis > 0 ? { dueAtMillis } : {},
|
|
2895
2897
|
...remindAtMillis > 0 ? { remindAtMillis } : {}
|
|
2896
2898
|
};
|
|
@@ -2911,20 +2913,20 @@ var ArrangementService = class {
|
|
|
2911
2913
|
const eventUid = stringValue$1(item.uid).trim();
|
|
2912
2914
|
const arrangementUid = stringValue$1(item.arrangement_uid).trim();
|
|
2913
2915
|
if (eventUid === "" || arrangementUid === "") throw new ArkmePluginError("arrangement-reminder-contract-invalid", "安排提醒响应缺少有效身份", true, 502);
|
|
2914
|
-
const dueAtMillis = Math.trunc(numberValue$
|
|
2915
|
-
const remindAtMillis = Math.trunc(numberValue$
|
|
2916
|
-
const readAtMillis = Math.trunc(numberValue$
|
|
2916
|
+
const dueAtMillis = Math.trunc(numberValue$24(item.due_at));
|
|
2917
|
+
const remindAtMillis = Math.trunc(numberValue$24(item.remind_at));
|
|
2918
|
+
const readAtMillis = Math.trunc(numberValue$24(item.read_at));
|
|
2917
2919
|
return {
|
|
2918
2920
|
eventRef: await this.arrangementReminderRef(viewerUserId, eventUid),
|
|
2919
2921
|
arrangementRef: await this.arrangementRef(viewerUserId, arrangementUid),
|
|
2920
2922
|
title: stringValue$1(item.title),
|
|
2921
2923
|
description: stringValue$1(item.description),
|
|
2922
2924
|
eventKind: stringValue$1(item.event_kind),
|
|
2923
|
-
eventAtMillis: Math.trunc(numberValue$
|
|
2925
|
+
eventAtMillis: Math.trunc(numberValue$24(item.event_at)),
|
|
2924
2926
|
read: readAtMillis > 0,
|
|
2925
2927
|
reminderState: stringValue$1(item.reminder_state),
|
|
2926
|
-
createdAtMillis: Math.trunc(numberValue$
|
|
2927
|
-
updatedAtMillis: Math.trunc(numberValue$
|
|
2928
|
+
createdAtMillis: Math.trunc(numberValue$24(item.create_at)),
|
|
2929
|
+
updatedAtMillis: Math.trunc(numberValue$24(item.update_at)),
|
|
2928
2930
|
...dueAtMillis > 0 ? { dueAtMillis } : {},
|
|
2929
2931
|
...remindAtMillis > 0 ? { remindAtMillis } : {},
|
|
2930
2932
|
...readAtMillis > 0 ? { readAtMillis } : {}
|
|
@@ -2981,7 +2983,7 @@ var ArrangementService = class {
|
|
|
2981
2983
|
const ARKME_PHONE_BIND_SUCCESS = 1;
|
|
2982
2984
|
const ARKME_PHONE_BIND_REPEAT = 2;
|
|
2983
2985
|
const ARKME_PHONE_BIND_CODE_ERR = 3;
|
|
2984
|
-
function numberValue$
|
|
2986
|
+
function numberValue$23(value) {
|
|
2985
2987
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2986
2988
|
}
|
|
2987
2989
|
function jiwoScanLoginAvailable(config) {
|
|
@@ -3066,7 +3068,7 @@ var AuthService = class {
|
|
|
3066
3068
|
const sceneStr = stringValue$1(data.scene_str).trim();
|
|
3067
3069
|
const pollToken = stringValue$1(data.poll_token).trim();
|
|
3068
3070
|
const qrContent = stringValue$1(data.url).trim();
|
|
3069
|
-
const expireSeconds = Math.max(30, numberValue$
|
|
3071
|
+
const expireSeconds = Math.max(30, numberValue$23(data.expire_seconds) || 300);
|
|
3070
3072
|
if (qrContent === "" && sceneStr !== "") throw new ArkmePluginError("wechat-qr-unavailable", "测试环境当前未返回可用微信二维码,请使用手机号登录", true, 503);
|
|
3071
3073
|
if (sceneStr === "" || pollToken === "" || qrContent === "") throw new ArkmePluginError("login-contract-invalid", "Arkme 登录二维码响应不完整", true, 502);
|
|
3072
3074
|
const attemptId = crypto.randomUUID();
|
|
@@ -3105,7 +3107,7 @@ var AuthService = class {
|
|
|
3105
3107
|
ref: 0,
|
|
3106
3108
|
keep_cancel: true
|
|
3107
3109
|
}, void 0, [200]);
|
|
3108
|
-
const userId = numberValue$
|
|
3110
|
+
const userId = numberValue$23(data.user_id);
|
|
3109
3111
|
if (userId <= 0) return {
|
|
3110
3112
|
status: "pending",
|
|
3111
3113
|
environment: this.runtime.config.environment,
|
|
@@ -3135,7 +3137,7 @@ var AuthService = class {
|
|
|
3135
3137
|
}, void 0, [200]);
|
|
3136
3138
|
const ticket = stringValue$1(data.ticket).trim();
|
|
3137
3139
|
const pollSecret = stringValue$1(data.poll_secret).trim();
|
|
3138
|
-
const expiresAtMillis = numberValue$
|
|
3140
|
+
const expiresAtMillis = numberValue$23(data.expires_at);
|
|
3139
3141
|
if (!/^[A-Za-z0-9_-]{43}$/.test(ticket) || !/^[A-Za-z0-9_-]{43}$/.test(pollSecret) || expiresAtMillis <= Date.now()) throw new ArkmePluginError("jiwo-login-contract-invalid", "即我登录二维码响应不完整", true, 502);
|
|
3140
3142
|
if (attemptGeneration !== this.jiwoAttemptGeneration) {
|
|
3141
3143
|
await this.cancelJiwoCredentials(ticket, pollSecret);
|
|
@@ -3185,7 +3187,7 @@ var AuthService = class {
|
|
|
3185
3187
|
};
|
|
3186
3188
|
}
|
|
3187
3189
|
if (status !== "authenticated") throw new ArkmePluginError("jiwo-login-contract-invalid", "即我扫码登录状态无效", true, 502);
|
|
3188
|
-
const userId = numberValue$
|
|
3190
|
+
const userId = numberValue$23(data.user_id);
|
|
3189
3191
|
const accessToken = stringValue$1(data.access_token);
|
|
3190
3192
|
const refreshToken = stringValue$1(data.refresh_token);
|
|
3191
3193
|
if (userId <= 0 || accessToken === "" || refreshToken === "") throw new ArkmePluginError("login-contract-invalid", "Arkme 登录成功响应缺少凭据", false, 502);
|
|
@@ -3254,7 +3256,7 @@ var AuthService = class {
|
|
|
3254
3256
|
const normalizedCaptcha = this.normalizedCaptcha(captcha);
|
|
3255
3257
|
const session = await this.runtime.sessionStore.read() ?? await this.runtime.readPendingBindingSession();
|
|
3256
3258
|
if (session !== void 0) {
|
|
3257
|
-
if (numberValue$
|
|
3259
|
+
if (numberValue$23((await this.runtime.post(this.runtime.config.authBaseUrl, "/api/v1/auth/bind-phone-send-code", {
|
|
3258
3260
|
phone: normalizedPhone,
|
|
3259
3261
|
pre: "86",
|
|
3260
3262
|
is_test: this.runtime.config.environment === "test",
|
|
@@ -3276,7 +3278,7 @@ var AuthService = class {
|
|
|
3276
3278
|
if (!/^[0-9]{6}$/.test(normalizedCode)) throw new ArkmePluginError("phone-code-invalid", "请输入有效的短信验证码", false);
|
|
3277
3279
|
const session = await this.runtime.sessionStore.read() ?? await this.runtime.readPendingBindingSession();
|
|
3278
3280
|
if (session !== void 0) {
|
|
3279
|
-
const result = numberValue$
|
|
3281
|
+
const result = numberValue$23((await this.runtime.post(this.runtime.config.authBaseUrl, "/api/v1/auth/verify-bind-phone", {
|
|
3280
3282
|
phone: normalizedPhone,
|
|
3281
3283
|
pre: "86",
|
|
3282
3284
|
code: normalizedCode,
|
|
@@ -3297,7 +3299,7 @@ var AuthService = class {
|
|
|
3297
3299
|
keep_cancel: true
|
|
3298
3300
|
}, void 0, [200]);
|
|
3299
3301
|
if (data.ok === false) throw new ArkmePluginError("phone-code-rejected", "手机号或验证码错误", false, 401);
|
|
3300
|
-
const userId = numberValue$
|
|
3302
|
+
const userId = numberValue$23(data.user_id);
|
|
3301
3303
|
const accessToken = stringValue$1(data.access_token);
|
|
3302
3304
|
const refreshToken = stringValue$1(data.refresh_token);
|
|
3303
3305
|
if (userId <= 0 || accessToken === "" || refreshToken === "") throw new ArkmePluginError("login-contract-invalid", "Arkme手机号登录响应不完整", false, 502);
|
|
@@ -3447,7 +3449,7 @@ var ArkmePrivacyVisibilityService = class {
|
|
|
3447
3449
|
};
|
|
3448
3450
|
//#endregion
|
|
3449
3451
|
//#region src/mention-metadata.ts
|
|
3450
|
-
function listValue$
|
|
3452
|
+
function listValue$24(value) {
|
|
3451
3453
|
return Array.isArray(value) ? value : [];
|
|
3452
3454
|
}
|
|
3453
3455
|
function integerLikeValue$3(value) {
|
|
@@ -3468,7 +3470,7 @@ function arkmeMentionMetadataFromRecord(record, payload) {
|
|
|
3468
3470
|
function arkmeMentionMetadataMentionsViewer(record, payload, viewerUserId) {
|
|
3469
3471
|
if (viewerUserId <= 0) return false;
|
|
3470
3472
|
const metadata = arkmeMentionMetadataFromRecord(record, payload);
|
|
3471
|
-
for (const rawMention of listValue$
|
|
3473
|
+
for (const rawMention of listValue$24(metadata.human_mentions ?? metadata.humanMentions)) {
|
|
3472
3474
|
const mention = objectValue$1(rawMention);
|
|
3473
3475
|
const mentionedUserId = integerLikeValue$3(mention.user_id ?? mention.userId);
|
|
3474
3476
|
if (mentionedUserId === 0 || mentionedUserId === viewerUserId) return true;
|
|
@@ -3736,7 +3738,7 @@ const GROUP_AVATAR_NEGATIVE_CACHE_TTL_MS = 6e4;
|
|
|
3736
3738
|
const TOPIC_DISSOLVE_RECORD_CONCURRENCY = 6;
|
|
3737
3739
|
const PRIVATE_REMARK_PAGE_LIMIT = 50;
|
|
3738
3740
|
const PRIVATE_REMARK_MAX_PAGES = 20;
|
|
3739
|
-
function numberValue$
|
|
3741
|
+
function numberValue$22(value) {
|
|
3740
3742
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
3741
3743
|
}
|
|
3742
3744
|
function integerIdentifierValue(value) {
|
|
@@ -3748,7 +3750,7 @@ function integerIdentifierValue(value) {
|
|
|
3748
3750
|
function booleanValue$12(value) {
|
|
3749
3751
|
return value === true;
|
|
3750
3752
|
}
|
|
3751
|
-
function listValue$
|
|
3753
|
+
function listValue$23(value) {
|
|
3752
3754
|
return Array.isArray(value) ? value : [];
|
|
3753
3755
|
}
|
|
3754
3756
|
function integerLikeValue$2(value) {
|
|
@@ -3788,7 +3790,7 @@ function arkmeChatSidebarTargetFromBundle(bundle, fallbackSubjectUid = "") {
|
|
|
3788
3790
|
if (subjectUid === "") return void 0;
|
|
3789
3791
|
return {
|
|
3790
3792
|
subjectUid,
|
|
3791
|
-
hiddenAnchorTimestamp: Math.max(0, numberValue$
|
|
3793
|
+
hiddenAnchorTimestamp: Math.max(0, numberValue$22(bundle.sort_active_at ?? bundle.last_active_at ?? chatSession.last_active_at))
|
|
3792
3794
|
};
|
|
3793
3795
|
}
|
|
3794
3796
|
function backendBooleanValue(value) {
|
|
@@ -3820,7 +3822,7 @@ function isSourceKind(value) {
|
|
|
3820
3822
|
function chatMessageDnd$1(value) {
|
|
3821
3823
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
3822
3824
|
const policy = value;
|
|
3823
|
-
return numberValue$
|
|
3825
|
+
return numberValue$22(policy.mute_state) === 2 || numberValue$22(policy.notify_state) === 2;
|
|
3824
3826
|
}
|
|
3825
3827
|
function attachmentPreviewKind(item) {
|
|
3826
3828
|
const fileName = stringValue$1(item.file_name ?? item.fileName).trim();
|
|
@@ -3839,13 +3841,13 @@ function arkmeChatConversationPreview(raw) {
|
|
|
3839
3841
|
const nested = stringValue$1(content.text_content ?? content.title ?? content.summary).trim();
|
|
3840
3842
|
if (nested !== "") return nested.slice(0, 300);
|
|
3841
3843
|
if (objectValue$1(content.voice).duration !== void 0) return "[语音]";
|
|
3842
|
-
const displayItems = listValue$
|
|
3844
|
+
const displayItems = listValue$23(raw.media_display_items ?? raw.mediaDisplayItems).map(objectValue$1);
|
|
3843
3845
|
const displayByAsset = /* @__PURE__ */ new Map();
|
|
3844
3846
|
for (const item of displayItems) {
|
|
3845
3847
|
const fileAssetUid = stringValue$1(item.file_asset_uid ?? item.fileAssetUid).trim();
|
|
3846
3848
|
if (fileAssetUid !== "") displayByAsset.set(fileAssetUid, item);
|
|
3847
3849
|
}
|
|
3848
|
-
const mediaRefs = listValue$
|
|
3850
|
+
const mediaRefs = listValue$23(content.media_refs ?? content.mediaRefs).map(objectValue$1);
|
|
3849
3851
|
const firstAttachment = (mediaRefs.length > 0 ? mediaRefs.map((ref) => ({
|
|
3850
3852
|
...displayByAsset.get(stringValue$1(ref.file_asset_uid ?? ref.fileAssetUid).trim()) ?? {},
|
|
3851
3853
|
...ref
|
|
@@ -3997,11 +3999,11 @@ var SourceService = class {
|
|
|
3997
3999
|
lane: "background-read",
|
|
3998
4000
|
key: `world-author-labels:${pageCursor === void 0 ? "first" : String(page)}`
|
|
3999
4001
|
});
|
|
4000
|
-
for (const raw of listValue$
|
|
4002
|
+
for (const raw of listValue$23(data.items)) {
|
|
4001
4003
|
const bundle = objectValue$1(raw);
|
|
4002
|
-
const sessionKind = numberValue$
|
|
4004
|
+
const sessionKind = numberValue$22(objectValue$1(bundle.session).session_kind);
|
|
4003
4005
|
if (sessionKind !== 1 && sessionKind !== 3) continue;
|
|
4004
|
-
const targetUserId = numberValue$
|
|
4006
|
+
const targetUserId = numberValue$22(objectValue$1(bundle.private_counterpart).user_id);
|
|
4005
4007
|
if (!remaining.has(targetUserId)) continue;
|
|
4006
4008
|
const supplement = objectValue$1(bundle.private_supplement);
|
|
4007
4009
|
const counterpart = objectValue$1(bundle.private_counterpart);
|
|
@@ -4035,7 +4037,7 @@ var SourceService = class {
|
|
|
4035
4037
|
key: `private-remarks:${String(offset)}`,
|
|
4036
4038
|
failureCooldownMs: 2e3
|
|
4037
4039
|
});
|
|
4038
|
-
const rawItems = listValue$
|
|
4040
|
+
const rawItems = listValue$23(data.items);
|
|
4039
4041
|
for (const value of rawItems) {
|
|
4040
4042
|
const raw = objectValue$1(value);
|
|
4041
4043
|
const targetUserId = integerIdentifierValue(raw.user_id);
|
|
@@ -4060,9 +4062,9 @@ var SourceService = class {
|
|
|
4060
4062
|
key: `private-remarks:direct:${pageCursor === void 0 ? "first" : String(page)}`,
|
|
4061
4063
|
failureCooldownMs: 2e3
|
|
4062
4064
|
});
|
|
4063
|
-
for (const value of listValue$
|
|
4065
|
+
for (const value of listValue$23(data.items)) {
|
|
4064
4066
|
const bundle = objectValue$1(value);
|
|
4065
|
-
const sessionKind = numberValue$
|
|
4067
|
+
const sessionKind = numberValue$22(objectValue$1(bundle.session).session_kind);
|
|
4066
4068
|
if (sessionKind !== 1 && sessionKind !== 3) continue;
|
|
4067
4069
|
const targetUserId = integerIdentifierValue(objectValue$1(bundle.private_counterpart).user_id);
|
|
4068
4070
|
if (!remaining.has(targetUserId)) continue;
|
|
@@ -4105,10 +4107,10 @@ var SourceService = class {
|
|
|
4105
4107
|
extra: { source: "dsh-arkme" }
|
|
4106
4108
|
}, session);
|
|
4107
4109
|
const topicUid = stringValue$1(created.topic_uid).trim();
|
|
4108
|
-
if (topicUid === "" || numberValue$
|
|
4110
|
+
if (topicUid === "" || numberValue$22(created.status) !== 1) throw new ArkmePluginError("topic-create-contract-invalid", "主题创建响应不完整", true, 502);
|
|
4109
4111
|
const sourceRef = await this.sealSourceRef(session.userId, "topic", topicUid, title);
|
|
4110
4112
|
if (parentTopicUid !== void 0) try {
|
|
4111
|
-
if (numberValue$
|
|
4113
|
+
if (numberValue$22(objectValue$1((await this.runtime.authenticatedPost("/api/v1/topics/hierarchy/bind", {
|
|
4112
4114
|
parent_topic_uid: parentTopicUid,
|
|
4113
4115
|
child_topic_uid: topicUid
|
|
4114
4116
|
}, session)).relation).status) !== 1) throw new ArkmePluginError("topic-hierarchy-bind-contract-invalid", "子主题层级响应不完整", true, 502);
|
|
@@ -4277,14 +4279,14 @@ var SourceService = class {
|
|
|
4277
4279
|
...cursorSendAt === void 0 ? {} : { cursor_send_at: cursorSendAt },
|
|
4278
4280
|
...cursorRecordUid === void 0 ? {} : { cursor_record_uid: cursorRecordUid }
|
|
4279
4281
|
}, session);
|
|
4280
|
-
for (const raw of listValue$
|
|
4282
|
+
for (const raw of listValue$23(data.records)) {
|
|
4281
4283
|
const item = objectValue$1(raw);
|
|
4282
4284
|
const uid = stringValue$1(item.record_uid ?? objectValue$1(item.record_core).record_uid).trim();
|
|
4283
4285
|
if (uid !== "") recordUids.add(uid);
|
|
4284
4286
|
}
|
|
4285
4287
|
onProgress?.(recordUids.size);
|
|
4286
4288
|
if (data.has_more !== true) return [...recordUids];
|
|
4287
|
-
const nextSendAt = numberValue$
|
|
4289
|
+
const nextSendAt = numberValue$22(data.next_cursor_send_at);
|
|
4288
4290
|
const nextRecordUid = stringValue$1(data.next_cursor_record_uid).trim();
|
|
4289
4291
|
const cursorKey = `${String(nextSendAt)}:${nextRecordUid}`;
|
|
4290
4292
|
if (nextSendAt <= 0 || nextRecordUid === "" || seenCursors.has(cursorKey)) throw new ArkmePluginError("topic-dissolve-record-page-invalid", "主题快记加载不完整,未解散主题,请刷新后重试", true, 502);
|
|
@@ -4367,7 +4369,7 @@ var SourceService = class {
|
|
|
4367
4369
|
parent_topic_uid: nextParentTopicUid ?? "",
|
|
4368
4370
|
insert_before_topic_uid: ""
|
|
4369
4371
|
}, session);
|
|
4370
|
-
return stringValue$1(moved.topic_uid).trim() === topicUid && stringValue$1(moved.parent_topic_uid).trim() === (nextParentTopicUid ?? "") && numberValue$
|
|
4372
|
+
return stringValue$1(moved.topic_uid).trim() === topicUid && stringValue$1(moved.parent_topic_uid).trim() === (nextParentTopicUid ?? "") && numberValue$22(moved.sibling_order) > 0;
|
|
4371
4373
|
}
|
|
4372
4374
|
async rollbackDissolvedTopicChildren(children, topicUid, parentTopicUid, session) {
|
|
4373
4375
|
for (const child of [...children].reverse()) await this.moveTopicHierarchyForDissolve(child.topic.ownerRef, parentTopicUid ?? "", topicUid, session).catch(() => false);
|
|
@@ -4396,7 +4398,7 @@ var SourceService = class {
|
|
|
4396
4398
|
}, session);
|
|
4397
4399
|
const movedTopicUid = stringValue$1(moved.topic_uid).trim();
|
|
4398
4400
|
const movedParentUid = stringValue$1(moved.parent_topic_uid).trim();
|
|
4399
|
-
const siblingOrder = numberValue$
|
|
4401
|
+
const siblingOrder = numberValue$22(moved.sibling_order);
|
|
4400
4402
|
if (movedTopicUid !== topic.ownerRef || movedParentUid !== (nextParentUid ?? "") || siblingOrder <= 0) throw new ArkmePluginError("topic-hierarchy-move-contract-invalid", "主题移动响应不完整,请刷新后重试", true, 502);
|
|
4401
4403
|
this.sourceListCache.clear();
|
|
4402
4404
|
return {
|
|
@@ -4441,17 +4443,17 @@ var SourceService = class {
|
|
|
4441
4443
|
if (source.kind !== "private_chat" && source.kind !== "group_chat") throw new ArkmePluginError("chat-directory-policy-invalid", "仅支持更新私聊或群聊的会话列表状态", false);
|
|
4442
4444
|
const sidebarTarget = await this.resolveChatSidebarTarget(source, session, options.signal);
|
|
4443
4445
|
const current = await this.runtime.authenticatedChatPost("/api/v1/chats/policy/get", { chat_session_uid: source.ownerRef }, session, options.signal);
|
|
4444
|
-
const pinned = options.pinned ?? numberValue$
|
|
4445
|
-
const hidden = options.hidden ?? numberValue$
|
|
4446
|
+
const pinned = options.pinned ?? numberValue$22(current.pin_state) === 2;
|
|
4447
|
+
const hidden = options.hidden ?? numberValue$22(current.show_in_home_state) === 2;
|
|
4446
4448
|
const updatedAt = Date.now();
|
|
4447
4449
|
const writes = [this.runtime.authenticatedChatPost("/api/v1/chats/policy/update", {
|
|
4448
4450
|
chat_session_uid: source.ownerRef,
|
|
4449
4451
|
show_in_home_state: hidden ? 2 : 1,
|
|
4450
|
-
privacy_state: numberValue$
|
|
4451
|
-
mute_state: numberValue$
|
|
4452
|
+
privacy_state: numberValue$22(current.privacy_state) || 1,
|
|
4453
|
+
mute_state: numberValue$22(current.mute_state) || 1,
|
|
4452
4454
|
pin_state: pinned ? 2 : 1,
|
|
4453
|
-
notify_state: numberValue$
|
|
4454
|
-
status: numberValue$
|
|
4455
|
+
notify_state: numberValue$22(current.notify_state) || 1,
|
|
4456
|
+
status: numberValue$22(current.status) || 1,
|
|
4455
4457
|
update_at: updatedAt
|
|
4456
4458
|
}, session, options.signal)];
|
|
4457
4459
|
if (options.hidden !== void 0) writes.push(this.runtime.authenticatedSubjectPost("/api/v1/subject/batch-set-sidebar-hidden-status", { items: [{
|
|
@@ -4510,7 +4512,7 @@ var SourceService = class {
|
|
|
4510
4512
|
key: "directory:groups:count",
|
|
4511
4513
|
failureCooldownMs: 2e3
|
|
4512
4514
|
});
|
|
4513
|
-
return Math.max(0, numberValue$
|
|
4515
|
+
return Math.max(0, numberValue$22(data.total ?? data.total_count));
|
|
4514
4516
|
}
|
|
4515
4517
|
async listSourcesUncached(session, directory, options, limit, sessionKind) {
|
|
4516
4518
|
if (directory === "send_to_self") {
|
|
@@ -4528,7 +4530,7 @@ var SourceService = class {
|
|
|
4528
4530
|
options.signal?.throwIfAborted();
|
|
4529
4531
|
const cached = summaryResult.status === "rejected" || latestRecordsResult.status === "rejected" ? await this.runtime.stateStore.cachedSnapshot(session.userId).catch(() => void 0) : void 0;
|
|
4530
4532
|
const defaultRecordCount = summaryResult.status === "fulfilled" ? summaryResult.value.recordCount : cached?.summary?.recordCount;
|
|
4531
|
-
const defaultLatestRecord = latestRecordsResult.status === "fulfilled" ? listValue$
|
|
4533
|
+
const defaultLatestRecord = latestRecordsResult.status === "fulfilled" ? listValue$23(latestRecordsResult.value.items).map((raw) => this.recordReader.isDSHAgentInput?.(raw) === true || this.recordReader.isPrivacyLocked?.(raw) === true || arkmePrivacyLockedRecord(raw) || lockedRecordUids.has(stringValue$1(objectValue$1(raw).record_uid ?? objectValue$1(objectValue$1(raw).record_core).record_uid).trim()) ? void 0 : this.recordReader.recordItem(raw)).find((item) => item !== void 0) : cached?.items.reduce((latest, item) => item.creationSource === 3 ? latest : latest === void 0 || item.sendAtMillis > latest.sendAtMillis ? item : latest, void 0);
|
|
4532
4534
|
const defaultLatestPreview = defaultLatestRecord === void 0 ? "" : defaultLatestRecord.textContent.trim() || defaultLatestRecord.title.trim();
|
|
4533
4535
|
const defaultCategory = {
|
|
4534
4536
|
sourceRef: await this.sealSourceRef(session.userId, "default_category", "uncategorized", "未分类"),
|
|
@@ -4544,24 +4546,24 @@ var SourceService = class {
|
|
|
4544
4546
|
const parentTopicUidByChild = /* @__PURE__ */ new Map();
|
|
4545
4547
|
const siblingOrderByChild = /* @__PURE__ */ new Map();
|
|
4546
4548
|
const childTopicUidsByParent = /* @__PURE__ */ new Map();
|
|
4547
|
-
for (const raw of listValue$
|
|
4549
|
+
for (const raw of listValue$23(hierarchyData?.relations)) {
|
|
4548
4550
|
const relation = objectValue$1(raw);
|
|
4549
|
-
if (numberValue$
|
|
4551
|
+
if (numberValue$22(relation.rel_kind) !== 1 || numberValue$22(relation.status) !== 1) continue;
|
|
4550
4552
|
const parentTopicUid = stringValue$1(relation.parent_topic_uid).trim();
|
|
4551
4553
|
const childTopicUid = stringValue$1(relation.child_topic_uid).trim();
|
|
4552
4554
|
if (parentTopicUid === "" || childTopicUid === "" || parentTopicUid === childTopicUid) continue;
|
|
4553
4555
|
parentTopicUidByChild.set(childTopicUid, parentTopicUid);
|
|
4554
|
-
siblingOrderByChild.set(childTopicUid, numberValue$
|
|
4556
|
+
siblingOrderByChild.set(childTopicUid, numberValue$22(relation.sibling_order));
|
|
4555
4557
|
const children = childTopicUidsByParent.get(parentTopicUid) ?? /* @__PURE__ */ new Set();
|
|
4556
4558
|
children.add(childTopicUid);
|
|
4557
4559
|
childTopicUidsByParent.set(parentTopicUid, children);
|
|
4558
4560
|
}
|
|
4559
|
-
for (const raw of listValue$
|
|
4561
|
+
for (const raw of listValue$23(data.items)) {
|
|
4560
4562
|
const item = objectValue$1(raw);
|
|
4561
4563
|
if (arkmePrivacyLockedTopic(item)) continue;
|
|
4562
4564
|
const core = objectValue$1(item.topic_core);
|
|
4563
4565
|
const status = core.status ?? item.status;
|
|
4564
|
-
if (status !== void 0 && numberValue$
|
|
4566
|
+
if (status !== void 0 && numberValue$22(status) !== 1) continue;
|
|
4565
4567
|
const summary = objectValue$1(item.summary);
|
|
4566
4568
|
const latest = objectValue$1(item.latest_record_core);
|
|
4567
4569
|
const parent = objectValue$1(core.parent_topic_core ?? core.parent_topic ?? item.parent_topic_core ?? item.parent_topic);
|
|
@@ -4573,12 +4575,12 @@ var SourceService = class {
|
|
|
4573
4575
|
topicDescriptors.push({
|
|
4574
4576
|
topicUid,
|
|
4575
4577
|
...parentTopicUid === "" || parentTopicUid === topicUid ? {} : { parentTopicUid },
|
|
4576
|
-
siblingOrder: numberValue$
|
|
4578
|
+
siblingOrder: numberValue$22(siblingOrderByChild.get(topicUid) ?? core.sibling_order ?? item.sibling_order),
|
|
4577
4579
|
title,
|
|
4578
4580
|
latestPreview: arkmeChatConversationPreview(latest),
|
|
4579
|
-
latestMessageAtMillis: numberValue$
|
|
4580
|
-
activeAtMillis: numberValue$
|
|
4581
|
-
recordCount: numberValue$
|
|
4581
|
+
latestMessageAtMillis: numberValue$22(latest.send_at ?? summary.latest_send_at),
|
|
4582
|
+
activeAtMillis: numberValue$22(latest.send_at ?? summary.latest_send_at ?? core.update_at),
|
|
4583
|
+
recordCount: numberValue$22(summary.record_count)
|
|
4582
4584
|
});
|
|
4583
4585
|
}
|
|
4584
4586
|
const sourceRefByTopicUid = /* @__PURE__ */ new Map();
|
|
@@ -4620,12 +4622,12 @@ var SourceService = class {
|
|
|
4620
4622
|
unreadCount: 0
|
|
4621
4623
|
};
|
|
4622
4624
|
const nextPageCursor = objectValue$1(data.next_page_cursor ?? data.next_cursor);
|
|
4623
|
-
const nextOffset = numberValue$
|
|
4625
|
+
const nextOffset = numberValue$22(data.next_offset);
|
|
4624
4626
|
const preferredPageCursor = Object.keys(nextPageCursor).length > 0 ? nextPageCursor : void 0;
|
|
4625
4627
|
const preferredOffset = preferredPageCursor === void 0 && nextOffset > 0 ? nextOffset : void 0;
|
|
4626
4628
|
const hasMore = data.has_more === true && (preferredPageCursor !== void 0 || preferredOffset !== void 0);
|
|
4627
4629
|
const totalValue = data.total ?? data.total_count;
|
|
4628
|
-
const total = totalValue === void 0 ? void 0 : Math.max(0, numberValue$
|
|
4630
|
+
const total = totalValue === void 0 ? void 0 : Math.max(0, numberValue$22(totalValue));
|
|
4629
4631
|
return {
|
|
4630
4632
|
directory,
|
|
4631
4633
|
items: [
|
|
@@ -4656,7 +4658,7 @@ var SourceService = class {
|
|
|
4656
4658
|
const items = [];
|
|
4657
4659
|
const privateUserIdByIndex = /* @__PURE__ */ new Map();
|
|
4658
4660
|
const groupSessionUidByIndex = /* @__PURE__ */ new Map();
|
|
4659
|
-
for (const raw of listValue$
|
|
4661
|
+
for (const raw of listValue$23(data.items)) {
|
|
4660
4662
|
const bundle = objectValue$1(raw);
|
|
4661
4663
|
const chatSession = objectValue$1(bundle.session);
|
|
4662
4664
|
const counterpart = objectValue$1(bundle.private_counterpart);
|
|
@@ -4667,14 +4669,14 @@ var SourceService = class {
|
|
|
4667
4669
|
const unread = objectValue$1(bundle.unread_snapshot);
|
|
4668
4670
|
const currentPolicy = objectValue$1(bundle.current_policy);
|
|
4669
4671
|
const isMuted = chatMessageDnd$1(currentPolicy) ?? false;
|
|
4670
|
-
const isPinned = numberValue$
|
|
4672
|
+
const isPinned = numberValue$22(currentPolicy.pin_state) === 2;
|
|
4671
4673
|
const uid = stringValue$1(chatSession.chat_session_uid).trim();
|
|
4672
|
-
const sessionKind = numberValue$
|
|
4674
|
+
const sessionKind = numberValue$22(chatSession.session_kind);
|
|
4673
4675
|
const kind = sessionKind === 2 ? "group_chat" : sessionKind === 1 || sessionKind === 3 ? "private_chat" : void 0;
|
|
4674
4676
|
if (uid === "" || kind === void 0) continue;
|
|
4675
4677
|
const displayName = (kind === "private_chat" ? stringValue$1(supplement.remark ?? supplement.counterpart_name_snapshot ?? counterpart.display_name_snapshot ?? supplement.pending_name ?? counterpart.visible_phone) : stringValue$1(chatSession.title)).trim() || "未命名会话";
|
|
4676
4678
|
const preview = arkmeChatConversationPreview(latestPayload);
|
|
4677
|
-
const unreadCount = Math.max(0, Math.trunc(numberValue$
|
|
4679
|
+
const unreadCount = Math.max(0, Math.trunc(numberValue$22(unread.unread_count)));
|
|
4678
4680
|
const latestRelation = objectValue$1(latestPreview.relation);
|
|
4679
4681
|
const latestPreviewMentionsViewer = integerLikeValue$2(latestRelation.sender_user_id ?? latestRelation.senderUserId) !== session.userId && arkmeMentionMetadataMentionsViewer(latestRecord, latestPayload, session.userId);
|
|
4680
4682
|
const backendMentionState = chatUnreadMentionState(unread);
|
|
@@ -4690,17 +4692,17 @@ var SourceService = class {
|
|
|
4690
4692
|
kind,
|
|
4691
4693
|
displayName,
|
|
4692
4694
|
...preview === "" ? {} : { latestPreview: preview },
|
|
4693
|
-
activeAtMillis: numberValue$
|
|
4695
|
+
activeAtMillis: numberValue$22(bundle.sort_active_at ?? chatSession.last_active_at),
|
|
4694
4696
|
unreadCount,
|
|
4695
4697
|
...hasUnreadMention === void 0 ? {} : { hasUnreadMention },
|
|
4696
4698
|
isMuted,
|
|
4697
4699
|
isPinned,
|
|
4698
|
-
...numberValue$
|
|
4700
|
+
...numberValue$22(unread.session_last_seq ?? chatSession.last_seq) > 0 ? { latestSequence: numberValue$22(unread.session_last_seq ?? chatSession.last_seq) } : {}
|
|
4699
4701
|
};
|
|
4700
4702
|
const itemIndex = items.push(item) - 1;
|
|
4701
4703
|
this.chatSourceCache.set(`${String(session.userId)}:${uid}`, item);
|
|
4702
4704
|
if (kind === "private_chat") {
|
|
4703
|
-
const counterpartUserId = numberValue$
|
|
4705
|
+
const counterpartUserId = numberValue$22(counterpart.user_id);
|
|
4704
4706
|
if (Number.isSafeInteger(counterpartUserId) && counterpartUserId > 0) {
|
|
4705
4707
|
item.peerUserId = counterpartUserId;
|
|
4706
4708
|
privateUserIdByIndex.set(itemIndex, counterpartUserId);
|
|
@@ -4714,7 +4716,7 @@ var SourceService = class {
|
|
|
4714
4716
|
}
|
|
4715
4717
|
const hasMore = data.has_more === true;
|
|
4716
4718
|
const totalValue = data.total ?? data.total_count;
|
|
4717
|
-
const total = totalValue === void 0 ? void 0 : Math.max(0, numberValue$
|
|
4719
|
+
const total = totalValue === void 0 ? void 0 : Math.max(0, numberValue$22(totalValue));
|
|
4718
4720
|
const nextPageCursor = objectValue$1(data.next_page_cursor);
|
|
4719
4721
|
return {
|
|
4720
4722
|
directory,
|
|
@@ -4770,16 +4772,16 @@ var SourceService = class {
|
|
|
4770
4772
|
continue;
|
|
4771
4773
|
}
|
|
4772
4774
|
const snapshotsByUid = /* @__PURE__ */ new Map();
|
|
4773
|
-
for (const raw of listValue$
|
|
4775
|
+
for (const raw of listValue$23(data.items)) {
|
|
4774
4776
|
const snapshot = objectValue$1(raw);
|
|
4775
4777
|
const uid = stringValue$1(snapshot.chat_session_uid).trim();
|
|
4776
4778
|
const index = indexByGroupUid.get(uid);
|
|
4777
4779
|
if (index === void 0 || !groupUids.includes(uid)) continue;
|
|
4778
|
-
const memberIds = listValue$
|
|
4780
|
+
const memberIds = listValue$23(snapshot.members).map((member) => numberValue$22(objectValue$1(member).user_id)).filter((userId) => Number.isSafeInteger(userId) && userId > 0).slice(0, 5);
|
|
4779
4781
|
const projection = {
|
|
4780
|
-
memberCount: Math.max(0, Math.trunc(numberValue$
|
|
4782
|
+
memberCount: Math.max(0, Math.trunc(numberValue$22(snapshot.member_count))),
|
|
4781
4783
|
strategy: stringValue$1(snapshot.strategy).trim(),
|
|
4782
|
-
computedAtMillis: numberValue$
|
|
4784
|
+
computedAtMillis: numberValue$22(snapshot.computed_at),
|
|
4783
4785
|
memberIds
|
|
4784
4786
|
};
|
|
4785
4787
|
snapshotsByUid.set(uid, projection);
|
|
@@ -4858,7 +4860,7 @@ var SourceService = class {
|
|
|
4858
4860
|
const kind = parsed.kind;
|
|
4859
4861
|
const result = {
|
|
4860
4862
|
version: 1,
|
|
4861
|
-
userId: numberValue$
|
|
4863
|
+
userId: numberValue$22(parsed.userId),
|
|
4862
4864
|
kind: isSourceKind(kind) ? kind : "default_category",
|
|
4863
4865
|
ownerRef: stringValue$1(parsed.ownerRef).trim(),
|
|
4864
4866
|
displayName: isSourceKind(kind) && kind === "default_category" ? "未分类" : stringValue$1(parsed.displayName).trim(),
|
|
@@ -4868,7 +4870,7 @@ var SourceService = class {
|
|
|
4868
4870
|
})() : {},
|
|
4869
4871
|
...kind === "private_chat" || kind === "group_chat" ? (() => {
|
|
4870
4872
|
const sidebarSubjectUid = stringValue$1(parsed.sidebarSubjectUid).trim();
|
|
4871
|
-
const sidebarHiddenAnchorTimestamp = Math.max(0, numberValue$
|
|
4873
|
+
const sidebarHiddenAnchorTimestamp = Math.max(0, numberValue$22(parsed.sidebarHiddenAnchorTimestamp));
|
|
4872
4874
|
return sidebarSubjectUid === "" ? {} : {
|
|
4873
4875
|
sidebarSubjectUid,
|
|
4874
4876
|
sidebarHiddenAnchorTimestamp
|
|
@@ -4902,16 +4904,16 @@ var SourceService = class {
|
|
|
4902
4904
|
const unread = objectValue$1(bundle.unread_snapshot);
|
|
4903
4905
|
const currentPolicy = objectValue$1(bundle.current_policy);
|
|
4904
4906
|
const isMuted = chatMessageDnd$1(currentPolicy) ?? cached?.isMuted ?? false;
|
|
4905
|
-
const isPinned = numberValue$
|
|
4907
|
+
const isPinned = numberValue$22(currentPolicy.pin_state) === 2;
|
|
4906
4908
|
const uid = stringValue$1(chatSession.chat_session_uid).trim();
|
|
4907
|
-
const sessionKind = numberValue$
|
|
4909
|
+
const sessionKind = numberValue$22(chatSession.session_kind);
|
|
4908
4910
|
const kind = sessionKind === 2 ? "group_chat" : sessionKind === 1 || sessionKind === 3 ? "private_chat" : void 0;
|
|
4909
4911
|
if (uid === "" || kind === void 0) throw new Error("invalid chat display snapshot");
|
|
4910
4912
|
const displayName = (kind === "private_chat" ? stringValue$1(supplement.remark ?? supplement.counterpart_name_snapshot ?? counterpart.display_name_snapshot ?? supplement.pending_name ?? counterpart.visible_phone) : stringValue$1(chatSession.title)).trim() || cached?.displayName || "未命名会话";
|
|
4911
4913
|
const latestItem = [...timelineItems].sort((left, right) => (right.sequence ?? 0) - (left.sequence ?? 0))[0];
|
|
4912
4914
|
const latestPreview = latestItem === void 0 ? cached?.latestPreview : latestItem.forwardRecords === void 0 ? arkmeTimelineConversationPreview(latestItem) : `[转发] ${latestItem.forwardRecords.title}`;
|
|
4913
|
-
const latestSequence = Math.max(numberValue$
|
|
4914
|
-
const unreadCount = Math.max(0, Math.trunc(numberValue$
|
|
4915
|
+
const latestSequence = Math.max(numberValue$22(unread.session_last_seq ?? chatSession.last_seq), latestItem?.sequence ?? 0, cached?.latestSequence ?? 0);
|
|
4916
|
+
const unreadCount = Math.max(0, Math.trunc(numberValue$22(unread.unread_count)));
|
|
4915
4917
|
const latestMentionsViewer = latestItem?.isMe === false && latestItem.mentionsViewer === true;
|
|
4916
4918
|
const backendMentionState = chatUnreadMentionState(unread);
|
|
4917
4919
|
const hasUnreadMention = kind !== "group_chat" ? void 0 : unreadCount <= 0 ? false : backendMentionState === void 0 && !latestMentionsViewer ? cached?.hasUnreadMention : backendMentionState === true || latestMentionsViewer;
|
|
@@ -4929,7 +4931,7 @@ var SourceService = class {
|
|
|
4929
4931
|
...cached?.avatarRefs === void 0 ? {} : { avatarRefs: cached.avatarRefs },
|
|
4930
4932
|
...cached?.groupAvatar === void 0 ? {} : { groupAvatar: cached.groupAvatar },
|
|
4931
4933
|
...latestPreview === void 0 || latestPreview === "" ? {} : { latestPreview },
|
|
4932
|
-
activeAtMillis: Math.max(numberValue$
|
|
4934
|
+
activeAtMillis: Math.max(numberValue$22(bundle.sort_active_at ?? chatSession.last_active_at), latestItem?.sendAtMillis ?? 0),
|
|
4933
4935
|
unreadCount,
|
|
4934
4936
|
...hasUnreadMention === void 0 ? {} : { hasUnreadMention },
|
|
4935
4937
|
isMuted,
|
|
@@ -4961,7 +4963,7 @@ var SourceService = class {
|
|
|
4961
4963
|
const value = this.decodeCursor(cursor);
|
|
4962
4964
|
if (value.directory !== "send_to_self") throw new ArkmePluginError("source-cursor-invalid", "发给自己的主题分页游标无效", false);
|
|
4963
4965
|
const pageCursor = objectValue$1(value.pageCursor);
|
|
4964
|
-
const offset = numberValue$
|
|
4966
|
+
const offset = numberValue$22(value.offset);
|
|
4965
4967
|
if (Object.keys(pageCursor).length === 0 && offset <= 0) throw new ArkmePluginError("source-cursor-invalid", "发给自己的主题分页游标无效", false);
|
|
4966
4968
|
return {
|
|
4967
4969
|
...Object.keys(pageCursor).length === 0 ? {} : { pageCursor },
|
|
@@ -4979,13 +4981,13 @@ const BOT_REF_TTL_MILLIS = 30 * 6e4;
|
|
|
4979
4981
|
const BOT_REF_CAP = 2e3;
|
|
4980
4982
|
const BOT_REF_PATTERN = /^arkme-bot-v2\.[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4981
4983
|
const BOT_IMAGE_REF_PATTERN = /^arkme-bot-image-v1\.[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4982
|
-
function numberValue$
|
|
4984
|
+
function numberValue$21(value) {
|
|
4983
4985
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
4984
4986
|
}
|
|
4985
4987
|
function booleanValue$11(value) {
|
|
4986
4988
|
return value === true;
|
|
4987
4989
|
}
|
|
4988
|
-
function listValue$
|
|
4990
|
+
function listValue$22(value) {
|
|
4989
4991
|
return Array.isArray(value) ? value : [];
|
|
4990
4992
|
}
|
|
4991
4993
|
function arkmeNormalizeBotProvider(value) {
|
|
@@ -4993,7 +4995,7 @@ function arkmeNormalizeBotProvider(value) {
|
|
|
4993
4995
|
if (normalized === "openclaw" || normalized === "webhook") return normalized;
|
|
4994
4996
|
}
|
|
4995
4997
|
function botPrivateChatTimestamp(value) {
|
|
4996
|
-
const numeric = numberValue$
|
|
4998
|
+
const numeric = numberValue$21(value);
|
|
4997
4999
|
if (numeric <= 0) return 0;
|
|
4998
5000
|
if (numeric < 1e10) return numeric * 1e3;
|
|
4999
5001
|
let millis = numeric;
|
|
@@ -5007,7 +5009,7 @@ function botWebhookSecurity(value) {
|
|
|
5007
5009
|
keyword: stringValue$1(raw.keyword).trim(),
|
|
5008
5010
|
tokenEnabled: booleanValue$11(raw.token_enabled ?? raw.signature_enabled),
|
|
5009
5011
|
ipWhitelistEnabled: booleanValue$11(raw.ip_whitelist_enabled),
|
|
5010
|
-
ipWhitelist: listValue$
|
|
5012
|
+
ipWhitelist: listValue$22(raw.ip_whitelist).map((item) => stringValue$1(item).trim()).filter((item) => item !== "").slice(0, 100)
|
|
5011
5013
|
};
|
|
5012
5014
|
}
|
|
5013
5015
|
function botProfileSource(data) {
|
|
@@ -5086,7 +5088,7 @@ var BotService = class {
|
|
|
5086
5088
|
}
|
|
5087
5089
|
async listBots(options = {}) {
|
|
5088
5090
|
const session = await this.runtime.requireSession();
|
|
5089
|
-
const rawBots = listValue$
|
|
5091
|
+
const rawBots = listValue$22((await this.runtime.authenticatedBotPost("/api/v1/bot/list", {}, session, options.signal)).bots).map(objectValue$1);
|
|
5090
5092
|
const candidates = rawBots.filter((raw) => stringValue$1(raw.bot_id).trim() !== "" && stringValue$1(raw.name).trim() !== "" && arkmeNormalizeBotProvider(raw.provider) !== void 0);
|
|
5091
5093
|
const chatTargetCounts = /* @__PURE__ */ new Map();
|
|
5092
5094
|
for (const raw of rawBots) {
|
|
@@ -5112,7 +5114,7 @@ var BotService = class {
|
|
|
5112
5114
|
async countBots(options = {}) {
|
|
5113
5115
|
const session = await this.runtime.requireSession();
|
|
5114
5116
|
const data = await this.runtime.authenticatedBotPost("/api/v1/bot/list", { limit: 0 }, session, options.signal);
|
|
5115
|
-
return Math.max(0, numberValue$
|
|
5117
|
+
return Math.max(0, numberValue$21(data.total ?? data.total_count));
|
|
5116
5118
|
}
|
|
5117
5119
|
async createBot(input, options = {}) {
|
|
5118
5120
|
const name = input.name.trim();
|
|
@@ -5248,7 +5250,7 @@ var BotService = class {
|
|
|
5248
5250
|
const groupTargetBody = await this.resolveGroupBotBindingBody(group, session, options.signal);
|
|
5249
5251
|
const data = await this.runtime.authenticatedBotPost("/api/v1/bot/group/list", groupTargetBody, session, options.signal);
|
|
5250
5252
|
const items = [];
|
|
5251
|
-
for (const value of listValue$
|
|
5253
|
+
for (const value of listValue$22(data.bots)) {
|
|
5252
5254
|
const raw = objectValue$1(value);
|
|
5253
5255
|
if (arkmeNormalizeBotProvider(raw.provider) !== "openclaw") continue;
|
|
5254
5256
|
const summary = await this.groupBotSummaryFromData(raw, session.userId);
|
|
@@ -5300,7 +5302,7 @@ var BotService = class {
|
|
|
5300
5302
|
}
|
|
5301
5303
|
async listMentionableGroupBots(group, session, signal) {
|
|
5302
5304
|
const groupTargetBody = await this.resolveGroupBotBindingBody(group, session, signal);
|
|
5303
|
-
return listValue$
|
|
5305
|
+
return listValue$22((await this.runtime.authenticatedBotPost("/api/v1/bot/group/list", groupTargetBody, session, signal)).bots).flatMap((value) => {
|
|
5304
5306
|
const raw = objectValue$1(value);
|
|
5305
5307
|
if (arkmeNormalizeBotProvider(raw.provider) !== "openclaw" || !booleanValue$11(raw.installed)) return [];
|
|
5306
5308
|
const botId = stringValue$1(raw.bot_id).trim();
|
|
@@ -5360,7 +5362,7 @@ var BotService = class {
|
|
|
5360
5362
|
const raw = botProfileSource(data);
|
|
5361
5363
|
if (stringValue$1(raw.bot_id).trim() !== reference.botId || arkmeNormalizeBotProvider(raw.provider) !== reference.provider) throw new ArkmePluginError("bot-contract-invalid", "Bot 配置响应与当前 Bot 不一致", true, 502);
|
|
5362
5364
|
const summary = await this.botSummaryFromData(raw, userId, reference.target);
|
|
5363
|
-
const joinedGroups = listValue$
|
|
5365
|
+
const joinedGroups = listValue$22(data.joined_groups).map((value) => objectValue$1(value)).map((group) => ({
|
|
5364
5366
|
title: stringValue$1(group.subject_title).trim() || stringValue$1(group.subject_uid).trim() || "未命名群聊",
|
|
5365
5367
|
installedAtMillis: botPrivateChatTimestamp(group.installed_at)
|
|
5366
5368
|
}));
|
|
@@ -5372,7 +5374,7 @@ var BotService = class {
|
|
|
5372
5374
|
tokenRevealEnabled: data.token_reveal_enabled !== false,
|
|
5373
5375
|
gatewayUrl: stringValue$1(data.gateway_url).trim(),
|
|
5374
5376
|
webhookUrl: stringValue$1(data.webhook_url).trim(),
|
|
5375
|
-
recordCount: Math.max(-1, Math.trunc(numberValue$
|
|
5377
|
+
recordCount: Math.max(-1, Math.trunc(numberValue$21(raw.record_count))),
|
|
5376
5378
|
webhookSecurity: botWebhookSecurity(data.webhook_security ?? raw.webhook_security),
|
|
5377
5379
|
joinedGroups
|
|
5378
5380
|
};
|
|
@@ -5499,14 +5501,14 @@ var BotService = class {
|
|
|
5499
5501
|
};
|
|
5500
5502
|
//#endregion
|
|
5501
5503
|
//#region src/services/bot-conversation-service.ts
|
|
5502
|
-
function numberValue$
|
|
5504
|
+
function numberValue$20(value) {
|
|
5503
5505
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
5504
5506
|
}
|
|
5505
|
-
function listValue$
|
|
5507
|
+
function listValue$21(value) {
|
|
5506
5508
|
return Array.isArray(value) ? value : [];
|
|
5507
5509
|
}
|
|
5508
5510
|
function botConversationTimestamp(value) {
|
|
5509
|
-
const numeric = numberValue$
|
|
5511
|
+
const numeric = numberValue$20(value);
|
|
5510
5512
|
if (numeric <= 0) return 0;
|
|
5511
5513
|
if (numeric < 1e10) return numeric * 1e3;
|
|
5512
5514
|
let millis = numeric;
|
|
@@ -5514,7 +5516,7 @@ function botConversationTimestamp(value) {
|
|
|
5514
5516
|
return millis;
|
|
5515
5517
|
}
|
|
5516
5518
|
function subjectAttachments(value) {
|
|
5517
|
-
return listValue$
|
|
5519
|
+
return listValue$21(value).map(objectValue$1).flatMap((raw) => {
|
|
5518
5520
|
const kind = stringValue$1(raw.kind).trim();
|
|
5519
5521
|
const fileName = stringValue$1(raw.file_name ?? raw.fileName).trim();
|
|
5520
5522
|
const mimeType = stringValue$1(raw.mime_type ?? raw.mimeType).trim();
|
|
@@ -5524,11 +5526,11 @@ function subjectAttachments(value) {
|
|
|
5524
5526
|
kind: kind || "file",
|
|
5525
5527
|
fileName,
|
|
5526
5528
|
mimeType,
|
|
5527
|
-
size: Math.max(0, Math.trunc(numberValue$
|
|
5528
|
-
durationMillis: Math.max(0, Math.trunc(numberValue$
|
|
5529
|
-
width: Math.max(0, Math.trunc(numberValue$
|
|
5530
|
-
height: Math.max(0, Math.trunc(numberValue$
|
|
5531
|
-
sortOrder: Math.max(0, Math.trunc(numberValue$
|
|
5529
|
+
size: Math.max(0, Math.trunc(numberValue$20(raw.size))),
|
|
5530
|
+
durationMillis: Math.max(0, Math.trunc(numberValue$20(raw.duration_ms ?? raw.durationMillis))),
|
|
5531
|
+
width: Math.max(0, Math.trunc(numberValue$20(raw.width))),
|
|
5532
|
+
height: Math.max(0, Math.trunc(numberValue$20(raw.height))),
|
|
5533
|
+
sortOrder: Math.max(0, Math.trunc(numberValue$20(raw.order ?? raw.sort_order ?? raw.sortOrder)))
|
|
5532
5534
|
}];
|
|
5533
5535
|
});
|
|
5534
5536
|
}
|
|
@@ -5597,7 +5599,7 @@ var SubjectBotConversationAdapter = class {
|
|
|
5597
5599
|
if (stringValue$1(objectValue$1(data.user_message).message_id).trim() === "") throw new ArkmePluginError("bot-conversation-send-outcome-unknown", "消息可能已发送,但响应缺少确认标识;请刷新会话确认", false, 409);
|
|
5598
5600
|
return {
|
|
5599
5601
|
userMessage: subjectMessage(data.user_message, content),
|
|
5600
|
-
botMessages: dedupeMessages([...listValue$
|
|
5602
|
+
botMessages: dedupeMessages([...listValue$21(data.bot_messages).map((message) => subjectMessage(message)), ...Object.keys(objectValue$1(data.bot_message)).length === 0 ? [] : [subjectMessage(data.bot_message)]]),
|
|
5601
5603
|
status: stringValue$1(data.status).trim() || "ok"
|
|
5602
5604
|
};
|
|
5603
5605
|
}
|
|
@@ -5615,7 +5617,7 @@ var SubjectBotConversationAdapter = class {
|
|
|
5615
5617
|
}
|
|
5616
5618
|
async read(context, signal) {
|
|
5617
5619
|
this.subjectTarget(context);
|
|
5618
|
-
return { messages: dedupeMessages(listValue$
|
|
5620
|
+
return { messages: dedupeMessages(listValue$21((await this.runtime.authenticatedBotPost("/api/v1/bot/private-chat/open", { bot_id: context.reference.botId }, context.session, signal)).messages).map((message) => subjectMessage(message))) };
|
|
5619
5621
|
}
|
|
5620
5622
|
subjectTarget(context) {
|
|
5621
5623
|
if (context.reference.target.kind !== "subject") throw new ArkmePluginError("bot-conversation-owner-mismatch", "Bot 会话 owner 不匹配", false, 409);
|
|
@@ -5739,14 +5741,14 @@ var BotConversationService = class {
|
|
|
5739
5741
|
//#region src/services/calendar-service.ts
|
|
5740
5742
|
const MAX_CALENDAR_RANGE_DAYS = 62;
|
|
5741
5743
|
const MAX_DAY_RECORD_LIMIT = 50;
|
|
5742
|
-
function numberValue$
|
|
5744
|
+
function numberValue$19(value) {
|
|
5743
5745
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
5744
5746
|
}
|
|
5745
5747
|
function booleanValue$10(value) {
|
|
5746
5748
|
if (typeof value === "boolean") return value;
|
|
5747
5749
|
if (typeof value === "number") return value !== 0;
|
|
5748
5750
|
}
|
|
5749
|
-
function listValue$
|
|
5751
|
+
function listValue$20(value) {
|
|
5750
5752
|
return Array.isArray(value) ? value : [];
|
|
5751
5753
|
}
|
|
5752
5754
|
function readCalendarDate(value, field) {
|
|
@@ -5779,7 +5781,7 @@ function boundedLimit$2(value) {
|
|
|
5779
5781
|
return limit;
|
|
5780
5782
|
}
|
|
5781
5783
|
function contentAccessState(value) {
|
|
5782
|
-
const code = Math.trunc(numberValue$
|
|
5784
|
+
const code = Math.trunc(numberValue$19(value));
|
|
5783
5785
|
if (code === 1) return "available";
|
|
5784
5786
|
if (code === 2) return "protected";
|
|
5785
5787
|
return "unknown";
|
|
@@ -5826,7 +5828,7 @@ var CalendarService = class {
|
|
|
5826
5828
|
endDate,
|
|
5827
5829
|
timezone: stringValue$1(data.timezone).trim() || timezone,
|
|
5828
5830
|
refreshedAtMillis: Date.now(),
|
|
5829
|
-
days: listValue$
|
|
5831
|
+
days: listValue$20(data.daily_data).map((raw) => this.bucketDay(raw)).filter((day) => day !== void 0)
|
|
5830
5832
|
};
|
|
5831
5833
|
}
|
|
5832
5834
|
async dayRecords(options) {
|
|
@@ -5852,14 +5854,14 @@ var CalendarService = class {
|
|
|
5852
5854
|
cacheMs: 1e4,
|
|
5853
5855
|
failureCooldownMs: 2e3
|
|
5854
5856
|
});
|
|
5855
|
-
const nextSendAt = Math.trunc(numberValue$
|
|
5857
|
+
const nextSendAt = Math.trunc(numberValue$19(data.next_cursor_send_at));
|
|
5856
5858
|
const nextUid = stringValue$1(data.next_cursor_record_uid).trim();
|
|
5857
5859
|
return {
|
|
5858
5860
|
scope: "self",
|
|
5859
5861
|
bucketDate,
|
|
5860
5862
|
timezone: stringValue$1(data.timezone).trim() || timezone,
|
|
5861
5863
|
refreshedAtMillis: Date.now(),
|
|
5862
|
-
items: listValue$
|
|
5864
|
+
items: listValue$20(data.items).filter((raw) => !arkmePrivacyLockedRecord(raw) && !lockedRecordUids.has(stringValue$1(objectValue$1(raw).record_uid ?? objectValue$1(objectValue$1(raw).record_core).record_uid).trim())).map((raw) => this.dayRecord(raw)).filter((item) => item !== void 0),
|
|
5863
5865
|
hasMore: data.has_more === true,
|
|
5864
5866
|
...nextSendAt > 0 && nextUid !== "" ? { nextCursor: {
|
|
5865
5867
|
sendAtMillis: nextSendAt,
|
|
@@ -5871,21 +5873,21 @@ var CalendarService = class {
|
|
|
5871
5873
|
const item = objectValue$1(raw);
|
|
5872
5874
|
const bucketDate = stringValue$1(item.bucket_date).trim();
|
|
5873
5875
|
if (bucketDate === "") return void 0;
|
|
5874
|
-
const protectedCount = Math.max(0, Math.trunc(numberValue$
|
|
5875
|
-
const count = Math.max(0, Math.trunc(numberValue$
|
|
5876
|
+
const protectedCount = Math.max(0, Math.trunc(numberValue$19(item.protected_count)));
|
|
5877
|
+
const count = Math.max(0, Math.trunc(numberValue$19(item.count)) - protectedCount);
|
|
5876
5878
|
return {
|
|
5877
5879
|
bucketDate,
|
|
5878
5880
|
count,
|
|
5879
5881
|
protectedCount: 0,
|
|
5880
5882
|
hasRecords: count > 0,
|
|
5881
|
-
...numberValue$
|
|
5883
|
+
...numberValue$19(item.first_send_at) > 0 ? { firstSendAtMillis: Math.trunc(numberValue$19(item.first_send_at)) } : {}
|
|
5882
5884
|
};
|
|
5883
5885
|
}
|
|
5884
5886
|
dayRecord(raw) {
|
|
5885
5887
|
const item = objectValue$1(raw);
|
|
5886
5888
|
const core = objectValue$1(item.record_core);
|
|
5887
5889
|
const recordUid = stringValue$1(item.record_uid ?? core.record_uid).trim();
|
|
5888
|
-
const sendAtMillis = Math.trunc(numberValue$
|
|
5890
|
+
const sendAtMillis = Math.trunc(numberValue$19(item.send_at ?? core.send_at));
|
|
5889
5891
|
if (recordUid === "" || sendAtMillis <= 0) return void 0;
|
|
5890
5892
|
const accessState = contentAccessState(core.content_access_state);
|
|
5891
5893
|
if (accessState === "protected" || arkmePrivacyLockedRecord(item)) return void 0;
|
|
@@ -5906,9 +5908,9 @@ var CalendarService = class {
|
|
|
5906
5908
|
preview,
|
|
5907
5909
|
...stringValue$1(topic.title).trim() === "" ? {} : { topicTitle: stringValue$1(topic.title).trim() },
|
|
5908
5910
|
sourceKind: sourceKind(item),
|
|
5909
|
-
creationSource: Math.trunc(numberValue$
|
|
5910
|
-
templateKind: Math.trunc(numberValue$
|
|
5911
|
-
displayKind: Math.trunc(numberValue$
|
|
5911
|
+
creationSource: Math.trunc(numberValue$19(core.creation_source)),
|
|
5912
|
+
templateKind: Math.trunc(numberValue$19(core.template_kind)),
|
|
5913
|
+
displayKind: Math.trunc(numberValue$19(core.display_kind)),
|
|
5912
5914
|
protected: false,
|
|
5913
5915
|
...isUncategorized === void 0 ? {} : { isUncategorized },
|
|
5914
5916
|
...hasManualEdit === void 0 ? {} : { hasManualEdit },
|
|
@@ -5918,10 +5920,10 @@ var CalendarService = class {
|
|
|
5918
5920
|
};
|
|
5919
5921
|
//#endregion
|
|
5920
5922
|
//#region src/services/call-history-service.ts
|
|
5921
|
-
function listValue$
|
|
5923
|
+
function listValue$19(value) {
|
|
5922
5924
|
return Array.isArray(value) ? value : [];
|
|
5923
5925
|
}
|
|
5924
|
-
function numberValue$
|
|
5926
|
+
function numberValue$18(value) {
|
|
5925
5927
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
5926
5928
|
if (typeof value === "string" && value.trim() !== "") {
|
|
5927
5929
|
const parsed = Number(value.trim());
|
|
@@ -5935,7 +5937,7 @@ function booleanValue$9(value) {
|
|
|
5935
5937
|
function firstValue(source, keys) {
|
|
5936
5938
|
for (const key of keys) if (source[key] !== void 0 && source[key] !== null) return source[key];
|
|
5937
5939
|
}
|
|
5938
|
-
function firstString(source, keys) {
|
|
5940
|
+
function firstString$1(source, keys) {
|
|
5939
5941
|
for (const key of keys) {
|
|
5940
5942
|
const value = stringValue$1(source[key]).trim();
|
|
5941
5943
|
if (value !== "") return value;
|
|
@@ -5944,25 +5946,25 @@ function firstString(source, keys) {
|
|
|
5944
5946
|
}
|
|
5945
5947
|
function firstNumber(source, keys) {
|
|
5946
5948
|
for (const key of keys) {
|
|
5947
|
-
const value = numberValue$
|
|
5949
|
+
const value = numberValue$18(source[key]);
|
|
5948
5950
|
if (value !== 0) return value;
|
|
5949
5951
|
}
|
|
5950
5952
|
return 0;
|
|
5951
5953
|
}
|
|
5952
|
-
function epochMillis(value) {
|
|
5953
|
-
const raw = numberValue$
|
|
5954
|
+
function epochMillis$1(value) {
|
|
5955
|
+
const raw = numberValue$18(value);
|
|
5954
5956
|
if (raw <= 0) return 0;
|
|
5955
5957
|
return raw < 1e10 ? Math.trunc(raw * 1e3) : Math.trunc(raw);
|
|
5956
5958
|
}
|
|
5957
5959
|
function firstEpochMillis(source, keys) {
|
|
5958
5960
|
for (const key of keys) {
|
|
5959
|
-
const value = epochMillis(source[key]);
|
|
5961
|
+
const value = epochMillis$1(source[key]);
|
|
5960
5962
|
if (value > 0) return value;
|
|
5961
5963
|
}
|
|
5962
5964
|
return 0;
|
|
5963
5965
|
}
|
|
5964
5966
|
function numberList(value) {
|
|
5965
|
-
return listValue$
|
|
5967
|
+
return listValue$19(value).map((item) => Math.trunc(numberValue$18(item))).filter((item) => Number.isSafeInteger(item) && item > 0);
|
|
5966
5968
|
}
|
|
5967
5969
|
function callMediaType(value) {
|
|
5968
5970
|
if (value === 0 || value === "0") return "audio";
|
|
@@ -6061,7 +6063,7 @@ function videoRecordCandidateObjects(raw) {
|
|
|
6061
6063
|
const item = objectValue$1(raw[key]);
|
|
6062
6064
|
if (Object.keys(item).length > 0) values.push(item);
|
|
6063
6065
|
}
|
|
6064
|
-
for (const key of arrayKeys) for (const item of listValue$
|
|
6066
|
+
for (const key of arrayKeys) for (const item of listValue$19(raw[key])) {
|
|
6065
6067
|
const value = objectValue$1(item);
|
|
6066
6068
|
if (Object.keys(value).length > 0) values.push(value);
|
|
6067
6069
|
}
|
|
@@ -6103,7 +6105,7 @@ function perspectiveFromItem(item, viewerUserId) {
|
|
|
6103
6105
|
"viewUserId"
|
|
6104
6106
|
]));
|
|
6105
6107
|
if (userId > 0) return userId === viewerUserId ? "self" : "peer";
|
|
6106
|
-
return perspectiveFromText(firstString(item, [
|
|
6108
|
+
return perspectiveFromText(firstString$1(item, [
|
|
6107
6109
|
"perspective",
|
|
6108
6110
|
"view",
|
|
6109
6111
|
"viewType",
|
|
@@ -6157,12 +6159,12 @@ function videoPerspectiveFromItem(item, viewerUserId) {
|
|
|
6157
6159
|
if (videoUrl === "" && posterUrl === "") return void 0;
|
|
6158
6160
|
return {
|
|
6159
6161
|
perspective: perspectiveFromItem(item, viewerUserId),
|
|
6160
|
-
...firstString(item, [
|
|
6162
|
+
...firstString$1(item, [
|
|
6161
6163
|
"label",
|
|
6162
6164
|
"display_name",
|
|
6163
6165
|
"displayName",
|
|
6164
6166
|
"name"
|
|
6165
|
-
]) === "" ? {} : { label: firstString(item, [
|
|
6167
|
+
]) === "" ? {} : { label: firstString$1(item, [
|
|
6166
6168
|
"label",
|
|
6167
6169
|
"display_name",
|
|
6168
6170
|
"displayName",
|
|
@@ -6275,7 +6277,7 @@ var CallHistoryService = class {
|
|
|
6275
6277
|
const validItems = (await Promise.all(this.historyItems(raw).map(async (item) => await this.normalizeHistoryItem(item, session.userId)))).filter((item) => item !== void 0);
|
|
6276
6278
|
await this.attachPeerAvatars(validItems, session, signal);
|
|
6277
6279
|
const hasMore = booleanValue$9(raw.has_more ?? raw.hasMore);
|
|
6278
|
-
const nextCursor = firstString(raw, [
|
|
6280
|
+
const nextCursor = firstString$1(raw, [
|
|
6279
6281
|
"next_cursor",
|
|
6280
6282
|
"nextCursor",
|
|
6281
6283
|
"cursor"
|
|
@@ -6313,7 +6315,7 @@ var CallHistoryService = class {
|
|
|
6313
6315
|
return Math.min(50, raw);
|
|
6314
6316
|
}
|
|
6315
6317
|
historyItems(raw) {
|
|
6316
|
-
return listValue$
|
|
6318
|
+
return listValue$19(firstValue(raw, [
|
|
6317
6319
|
"items",
|
|
6318
6320
|
"records",
|
|
6319
6321
|
"histories",
|
|
@@ -6326,9 +6328,9 @@ var CallHistoryService = class {
|
|
|
6326
6328
|
...raw,
|
|
6327
6329
|
...trtc
|
|
6328
6330
|
};
|
|
6329
|
-
const roomId = firstString(item, ["room_id", "roomId"]);
|
|
6331
|
+
const roomId = firstString$1(item, ["room_id", "roomId"]);
|
|
6330
6332
|
if (roomId === "") return void 0;
|
|
6331
|
-
const stableId = firstString(raw, ["stable_id", "stableId"]) || `trtc:${roomId}`;
|
|
6333
|
+
const stableId = firstString$1(raw, ["stable_id", "stableId"]) || `trtc:${roomId}`;
|
|
6332
6334
|
const startedAtMillis = firstEpochMillis(item, [
|
|
6333
6335
|
"started_at_millis",
|
|
6334
6336
|
"startedAtMillis",
|
|
@@ -6350,7 +6352,7 @@ var CallHistoryService = class {
|
|
|
6350
6352
|
"endTime"
|
|
6351
6353
|
]);
|
|
6352
6354
|
const duration = durationSeconds(acceptedAtMillis, startedAtMillis, endedAtMillis);
|
|
6353
|
-
const callResult = firstString(item, [
|
|
6355
|
+
const callResult = firstString$1(item, [
|
|
6354
6356
|
"call_result",
|
|
6355
6357
|
"callResult",
|
|
6356
6358
|
"result"
|
|
@@ -6359,7 +6361,7 @@ var CallHistoryService = class {
|
|
|
6359
6361
|
const calleeUserIds = numberList(item.callee_user_ids ?? item.calleeUserIds);
|
|
6360
6362
|
const connectedUserIds = numberList(item.connected_user_ids ?? item.connectedUserIds);
|
|
6361
6363
|
const peerUserId = this.resolvePeerUserId(viewerUserId, callerUserId, calleeUserIds, connectedUserIds, item);
|
|
6362
|
-
const summaryText = safeSummary(firstString(item, [
|
|
6364
|
+
const summaryText = safeSummary(firstString$1(item, [
|
|
6363
6365
|
"call_summary",
|
|
6364
6366
|
"callSummary",
|
|
6365
6367
|
"summary_text",
|
|
@@ -6372,7 +6374,7 @@ var CallHistoryService = class {
|
|
|
6372
6374
|
"summary_updated_at",
|
|
6373
6375
|
"summaryUpdatedAt"
|
|
6374
6376
|
]);
|
|
6375
|
-
const displayName = firstString(item, [
|
|
6377
|
+
const displayName = firstString$1(item, [
|
|
6376
6378
|
"peer_display_name",
|
|
6377
6379
|
"peerDisplayName",
|
|
6378
6380
|
"display_name",
|
|
@@ -6413,12 +6415,12 @@ var CallHistoryService = class {
|
|
|
6413
6415
|
...summaryUpdatedAtMillis > 0 ? { summaryUpdatedAtMillis } : {},
|
|
6414
6416
|
canOpenDetail: true,
|
|
6415
6417
|
canRedial: peerUserId > 0,
|
|
6416
|
-
...firstString(item, [
|
|
6418
|
+
...firstString$1(item, [
|
|
6417
6419
|
"chat_session_uid",
|
|
6418
6420
|
"chatSessionUid",
|
|
6419
6421
|
"resolved_chat_session_uid",
|
|
6420
6422
|
"resolvedChatSessionUid"
|
|
6421
|
-
]) === "" ? {} : { chatSessionUid: firstString(item, [
|
|
6423
|
+
]) === "" ? {} : { chatSessionUid: firstString$1(item, [
|
|
6422
6424
|
"chat_session_uid",
|
|
6423
6425
|
"chatSessionUid",
|
|
6424
6426
|
"resolved_chat_session_uid",
|
|
@@ -6449,7 +6451,7 @@ var CallHistoryService = class {
|
|
|
6449
6451
|
return [...calleeUserIds, ...connectedUserIds].find((userId) => userId > 0 && userId !== viewerUserId) ?? 0;
|
|
6450
6452
|
}
|
|
6451
6453
|
async recentContacts(raw, session, signal) {
|
|
6452
|
-
const rawContacts = listValue$
|
|
6454
|
+
const rawContacts = listValue$19(firstValue(raw, ["recent_contacts", "recentContacts"]));
|
|
6453
6455
|
if (rawContacts.length > 0) {
|
|
6454
6456
|
const contacts = rawContacts.map((item) => this.recentContactFromRaw(objectValue$1(item))).filter((item) => item !== void 0);
|
|
6455
6457
|
if (contacts.length > 0) return await this.attachRecentContactAvatars(contacts, session, signal);
|
|
@@ -6511,7 +6513,7 @@ var CallHistoryService = class {
|
|
|
6511
6513
|
"peerUserId"
|
|
6512
6514
|
]));
|
|
6513
6515
|
if (userId <= 0) return void 0;
|
|
6514
|
-
const displayName = firstString(raw, [
|
|
6516
|
+
const displayName = firstString$1(raw, [
|
|
6515
6517
|
"display_name",
|
|
6516
6518
|
"displayName",
|
|
6517
6519
|
"peer_display_name",
|
|
@@ -6556,12 +6558,12 @@ var CallHistoryService = class {
|
|
|
6556
6558
|
"endTime"
|
|
6557
6559
|
]);
|
|
6558
6560
|
const duration = durationSeconds(acceptedAtMillis, startedAtMillis, endedAtMillis);
|
|
6559
|
-
const callResult = firstString(raw, [
|
|
6561
|
+
const callResult = firstString$1(raw, [
|
|
6560
6562
|
"call_result",
|
|
6561
6563
|
"callResult",
|
|
6562
6564
|
"result"
|
|
6563
6565
|
]);
|
|
6564
|
-
const summaryText = safeSummary(firstString(raw, [
|
|
6566
|
+
const summaryText = safeSummary(firstString$1(raw, [
|
|
6565
6567
|
"call_summary",
|
|
6566
6568
|
"callSummary",
|
|
6567
6569
|
"summary_text",
|
|
@@ -6587,7 +6589,7 @@ var CallHistoryService = class {
|
|
|
6587
6589
|
...payload,
|
|
6588
6590
|
issuedAtMillis: Date.now()
|
|
6589
6591
|
}),
|
|
6590
|
-
title: firstString(raw, [
|
|
6592
|
+
title: firstString$1(raw, [
|
|
6591
6593
|
"title",
|
|
6592
6594
|
"display_name",
|
|
6593
6595
|
"displayName",
|
|
@@ -6630,14 +6632,14 @@ var CallHistoryService = class {
|
|
|
6630
6632
|
}));
|
|
6631
6633
|
}
|
|
6632
6634
|
participants(raw, viewerUserId) {
|
|
6633
|
-
return listValue$
|
|
6635
|
+
return listValue$19(firstValue(raw, [
|
|
6634
6636
|
"participants",
|
|
6635
6637
|
"participant_profiles",
|
|
6636
6638
|
"participantProfiles"
|
|
6637
6639
|
])).map((item) => {
|
|
6638
6640
|
const rawItem = objectValue$1(item);
|
|
6639
6641
|
const userId = Math.trunc(firstNumber(rawItem, ["user_id", "userId"]));
|
|
6640
|
-
const displayName = firstString(rawItem, [
|
|
6642
|
+
const displayName = firstString$1(rawItem, [
|
|
6641
6643
|
"display_name",
|
|
6642
6644
|
"displayName",
|
|
6643
6645
|
"name",
|
|
@@ -6653,19 +6655,19 @@ var CallHistoryService = class {
|
|
|
6653
6655
|
}).filter((item) => item !== void 0).slice(0, 50);
|
|
6654
6656
|
}
|
|
6655
6657
|
transcriptSegments(raw) {
|
|
6656
|
-
return listValue$
|
|
6658
|
+
return listValue$19(firstValue(raw, [
|
|
6657
6659
|
"segments",
|
|
6658
6660
|
"transcript_segments",
|
|
6659
6661
|
"room_transcript_segments"
|
|
6660
6662
|
])).map((item, index) => {
|
|
6661
6663
|
const rawItem = objectValue$1(item);
|
|
6662
|
-
const text = clippedText(firstString(rawItem, [
|
|
6664
|
+
const text = clippedText(firstString$1(rawItem, [
|
|
6663
6665
|
"text",
|
|
6664
6666
|
"transcript",
|
|
6665
6667
|
"content"
|
|
6666
6668
|
]), 2e3);
|
|
6667
6669
|
if (text === "") return void 0;
|
|
6668
|
-
const segmentId = firstString(rawItem, [
|
|
6670
|
+
const segmentId = firstString$1(rawItem, [
|
|
6669
6671
|
"segment_id",
|
|
6670
6672
|
"segmentId",
|
|
6671
6673
|
"id"
|
|
@@ -6678,7 +6680,7 @@ var CallHistoryService = class {
|
|
|
6678
6680
|
]));
|
|
6679
6681
|
return {
|
|
6680
6682
|
segmentId,
|
|
6681
|
-
speakerDisplayName: firstString(rawItem, [
|
|
6683
|
+
speakerDisplayName: firstString$1(rawItem, [
|
|
6682
6684
|
"speaker_display_name",
|
|
6683
6685
|
"speakerDisplayName",
|
|
6684
6686
|
"speaker_name",
|
|
@@ -6727,11 +6729,11 @@ var CallHistoryService = class {
|
|
|
6727
6729
|
}
|
|
6728
6730
|
const value = objectValue$1(payload);
|
|
6729
6731
|
const parsed = {
|
|
6730
|
-
version: numberValue$
|
|
6731
|
-
userId: numberValue$
|
|
6732
|
+
version: numberValue$18(value.version),
|
|
6733
|
+
userId: numberValue$18(value.userId),
|
|
6732
6734
|
roomId: stringValue$1(value.roomId).trim(),
|
|
6733
6735
|
stableId: stringValue$1(value.stableId).trim(),
|
|
6734
|
-
issuedAtMillis: numberValue$
|
|
6736
|
+
issuedAtMillis: numberValue$18(value.issuedAtMillis)
|
|
6735
6737
|
};
|
|
6736
6738
|
if (parsed.version !== 1 || parsed.userId !== expectedUserId || parsed.roomId === "" || parsed.stableId === "") throw new ArkmePluginError("call-ref-invalid", "通话记录引用无效,请重新查询通话记录", false, 400);
|
|
6737
6739
|
return parsed;
|
|
@@ -7188,7 +7190,7 @@ var ArkmeChatRealtimeRuntime = class {
|
|
|
7188
7190
|
//#endregion
|
|
7189
7191
|
//#region src/services/chat-realtime-service.ts
|
|
7190
7192
|
const MAX_PROJECTION_RETRIES = 5;
|
|
7191
|
-
function listValue$
|
|
7193
|
+
function listValue$18(value) {
|
|
7192
7194
|
return Array.isArray(value) ? value : [];
|
|
7193
7195
|
}
|
|
7194
7196
|
function safeFailureMessage$5(error) {
|
|
@@ -7340,6 +7342,7 @@ var ChatRealtimeService = class {
|
|
|
7340
7342
|
const session = await this.runtime.sessionStore.read();
|
|
7341
7343
|
if (session === void 0) return;
|
|
7342
7344
|
this.source.invalidateSourceListCache(session.userId, "send_to_self");
|
|
7345
|
+
this.runtime.invalidateKey(this.runtime.requestScope(session.userId), "calendar:");
|
|
7343
7346
|
this.emitChatClientEvent({
|
|
7344
7347
|
type: "projection-invalidated",
|
|
7345
7348
|
revision: this.nextChatClientRevision(),
|
|
@@ -7480,7 +7483,7 @@ var ChatRealtimeService = class {
|
|
|
7480
7483
|
lane: "background-read",
|
|
7481
7484
|
key: `projection:display:${projectionBatchKey}`
|
|
7482
7485
|
});
|
|
7483
|
-
const bundles = new Map(listValue$
|
|
7486
|
+
const bundles = new Map(listValue$18(displayData.items).map((raw) => {
|
|
7484
7487
|
const bundle = objectValue$1(raw);
|
|
7485
7488
|
return [stringValue$1(objectValue$1(bundle.session).chat_session_uid).trim(), bundle];
|
|
7486
7489
|
}).filter(([uid]) => uid !== ""));
|
|
@@ -7570,6 +7573,7 @@ var ChatRealtimeService = class {
|
|
|
7570
7573
|
}
|
|
7571
7574
|
if (updates.length > 0) {
|
|
7572
7575
|
this.source.invalidateSourceListCache(session.userId, "root");
|
|
7576
|
+
this.runtime.invalidateKey(this.runtime.requestScope(session.userId), "calendar:");
|
|
7573
7577
|
this.emitChatClientEvent({
|
|
7574
7578
|
type: "sessions-delta",
|
|
7575
7579
|
revision: this.nextChatClientRevision(),
|
|
@@ -7601,17 +7605,794 @@ const ARKME_VOICEPRINT_ENROLLMENT_MAX_AUDIO_BYTES = 10 * 1024 * 1024;
|
|
|
7601
7605
|
const ARKME_WORLD_PUBLISH_MAX_IMAGES = 27;
|
|
7602
7606
|
const ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
7603
7607
|
//#endregion
|
|
7608
|
+
//#region src/services/record-service.ts
|
|
7609
|
+
function numberValue$17(value) {
|
|
7610
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
7611
|
+
}
|
|
7612
|
+
function listValue$17(value) {
|
|
7613
|
+
return Array.isArray(value) ? value : [];
|
|
7614
|
+
}
|
|
7615
|
+
const DSH_AGENT_INPUT_CREATION_SOURCE = 3;
|
|
7616
|
+
const MAX_DEFAULT_CATEGORY_FILTER_BACKFILL_PAGES = 5;
|
|
7617
|
+
function integerLikeValue$1(value) {
|
|
7618
|
+
if (typeof value === "number" && Number.isFinite(value)) return Math.trunc(value);
|
|
7619
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
7620
|
+
const parsed = Number(value.trim());
|
|
7621
|
+
if (Number.isFinite(parsed)) return Math.trunc(parsed);
|
|
7622
|
+
}
|
|
7623
|
+
return 0;
|
|
7624
|
+
}
|
|
7625
|
+
function recordCreationSource(raw) {
|
|
7626
|
+
const item = objectValue$1(raw);
|
|
7627
|
+
const core = objectValue$1(item.record_core);
|
|
7628
|
+
return integerLikeValue$1(item.creation_source ?? item.creationSource ?? core.creation_source ?? core.creationSource);
|
|
7629
|
+
}
|
|
7630
|
+
function isDSHAgentInputRecord(raw) {
|
|
7631
|
+
return recordCreationSource(raw) === DSH_AGENT_INPUT_CREATION_SOURCE;
|
|
7632
|
+
}
|
|
7633
|
+
function safeFailureMessage$4(error) {
|
|
7634
|
+
if (error instanceof ArkmePluginError) return error.message;
|
|
7635
|
+
if (error instanceof Error && error.message.trim() !== "") return error.message;
|
|
7636
|
+
return "未知错误";
|
|
7637
|
+
}
|
|
7638
|
+
function arkmeRecordCaptureContextPayload(input) {
|
|
7639
|
+
const clientName = input.clientName?.trim().slice(0, 120) ?? "";
|
|
7640
|
+
const networkName = input.networkName?.trim().slice(0, 120) ?? "";
|
|
7641
|
+
const electric = input.electric === void 0 ? void 0 : Math.trunc(input.electric);
|
|
7642
|
+
const charge = Math.trunc(input.charge ?? 0);
|
|
7643
|
+
return {
|
|
7644
|
+
...clientName === "" ? {} : { client_name: clientName },
|
|
7645
|
+
...networkName === "" ? {} : { network_name: networkName },
|
|
7646
|
+
...electric === void 0 || electric < 0 || electric > 100 ? {} : { electric },
|
|
7647
|
+
...charge < 1 || charge > 3 ? {} : { charge }
|
|
7648
|
+
};
|
|
7649
|
+
}
|
|
7650
|
+
function normalizedRecordCaptureContext(input) {
|
|
7651
|
+
if (input === void 0) return void 0;
|
|
7652
|
+
const payload = arkmeRecordCaptureContextPayload(input);
|
|
7653
|
+
const clientName = stringValue$1(payload.client_name);
|
|
7654
|
+
const networkName = stringValue$1(payload.network_name);
|
|
7655
|
+
const electric = numberValue$17(payload.electric);
|
|
7656
|
+
const charge = numberValue$17(payload.charge);
|
|
7657
|
+
const normalized = {
|
|
7658
|
+
...clientName === "" ? {} : { clientName },
|
|
7659
|
+
...networkName === "" ? {} : { networkName },
|
|
7660
|
+
...payload.electric === void 0 ? {} : { electric },
|
|
7661
|
+
...charge === 0 ? {} : { charge }
|
|
7662
|
+
};
|
|
7663
|
+
return Object.keys(normalized).length === 0 ? void 0 : normalized;
|
|
7664
|
+
}
|
|
7665
|
+
var RecordService = class {
|
|
7666
|
+
runtime;
|
|
7667
|
+
media;
|
|
7668
|
+
source;
|
|
7669
|
+
privacy;
|
|
7670
|
+
constructor(runtime, media, source, privacy = new ArkmePrivacyVisibilityService(runtime)) {
|
|
7671
|
+
this.runtime = runtime;
|
|
7672
|
+
this.media = media;
|
|
7673
|
+
this.source = source;
|
|
7674
|
+
this.privacy = privacy;
|
|
7675
|
+
}
|
|
7676
|
+
async longArticleDetail(sourceRef, itemUid, signal) {
|
|
7677
|
+
const session = await this.runtime.requireSession();
|
|
7678
|
+
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
7679
|
+
const uid = itemUid.trim();
|
|
7680
|
+
if (uid === "") throw new ArkmePluginError("long-article-item-invalid", "长文记录标识无效", false);
|
|
7681
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/detail", { record_uid: uid }, session, signal);
|
|
7682
|
+
const core = objectValue$1(data.record_core);
|
|
7683
|
+
const recordUid = stringValue$1(core.record_uid).trim();
|
|
7684
|
+
const templateKind = numberValue$17(core.template_kind);
|
|
7685
|
+
const displayKind = numberValue$17(core.display_kind);
|
|
7686
|
+
if (recordUid !== uid || templateKind !== 8 && displayKind !== 1) throw new ArkmePluginError("long-article-not-found", "未找到可用的长文详情", false, 404);
|
|
7687
|
+
const originContainerRef = stringValue$1(core.origin_container_ref).trim();
|
|
7688
|
+
if (source.kind === "topic") {
|
|
7689
|
+
if (stringValue$1(objectValue$1(data.topic_core).topic_uid).trim() !== source.ownerRef) throw new ArkmePluginError("long-article-source-mismatch", "长文不属于当前会话", false, 403);
|
|
7690
|
+
} else if (source.kind === "private_chat" || source.kind === "group_chat") {
|
|
7691
|
+
if (originContainerRef !== source.ownerRef) throw new ArkmePluginError("long-article-source-mismatch", "长文不属于当前会话", false, 403);
|
|
7692
|
+
} else if (numberValue$17(core.owner_user_id) !== session.userId) throw new ArkmePluginError("long-article-source-mismatch", "长文不属于当前会话", false, 403);
|
|
7693
|
+
const recordDurationMillis = Math.max(0, Math.trunc(numberValue$17(core.record_duration_millis)));
|
|
7694
|
+
const editDurationMillis = Math.max(0, Math.trunc(numberValue$17(core.edit_duration_millis)));
|
|
7695
|
+
return {
|
|
7696
|
+
sourceRef,
|
|
7697
|
+
itemUid: recordUid,
|
|
7698
|
+
title: stringValue$1(core.title),
|
|
7699
|
+
textContent: stringValue$1(core.text_content),
|
|
7700
|
+
sendAtMillis: Math.trunc(numberValue$17(core.send_at)),
|
|
7701
|
+
updateAtMillis: Math.trunc(numberValue$17(core.update_at)),
|
|
7702
|
+
recordDurationMillis,
|
|
7703
|
+
editDurationMillis,
|
|
7704
|
+
thinkingDurationMillis: recordDurationMillis + editDurationMillis,
|
|
7705
|
+
version: Math.trunc(numberValue$17(core.version)),
|
|
7706
|
+
editable: numberValue$17(core.owner_user_id) === session.userId && numberValue$17(core.creator_user_id) === session.userId
|
|
7707
|
+
};
|
|
7708
|
+
}
|
|
7709
|
+
async updateLongArticle(sourceRef, itemUid, input) {
|
|
7710
|
+
if (this.runtime.config.richMediaSendEnabled === false) throw new ArkmePluginError("rich-content-disabled", "长文编辑已被插件配置关闭", false, 403);
|
|
7711
|
+
const session = await this.runtime.requireSession();
|
|
7712
|
+
const detail = await this.longArticleDetail(sourceRef, itemUid);
|
|
7713
|
+
const title = input.title.trim();
|
|
7714
|
+
const textContent = input.textContent.trim();
|
|
7715
|
+
const editDurationMillis = Math.max(0, Math.trunc(input.editDurationMillis));
|
|
7716
|
+
if (!detail.editable) throw new ArkmePluginError("long-article-not-editable", "只能编辑自己发布的长文", false, 403);
|
|
7717
|
+
if (title === "" || title.length > 100 || textContent === "" || textContent.length > 4e4 || !Number.isSafeInteger(input.version) || input.version <= 0 || input.version !== detail.version) throw new ArkmePluginError("long-article-update-invalid", "长文内容或版本无效,请刷新后重试", false, 409);
|
|
7718
|
+
await this.runtime.authenticatedPost("/api/v1/records/update", {
|
|
7719
|
+
record_uid: detail.itemUid,
|
|
7720
|
+
template_kind: 1,
|
|
7721
|
+
display_kind: 1,
|
|
7722
|
+
title,
|
|
7723
|
+
text_content: textContent,
|
|
7724
|
+
record_duration_millis: detail.recordDurationMillis,
|
|
7725
|
+
edit_duration_millis: editDurationMillis,
|
|
7726
|
+
version: detail.version
|
|
7727
|
+
}, session);
|
|
7728
|
+
return await this.longArticleDetail(sourceRef, itemUid);
|
|
7729
|
+
}
|
|
7730
|
+
async getLongArticleDraft(sourceRef, itemUid) {
|
|
7731
|
+
const session = await this.runtime.requireSession();
|
|
7732
|
+
await this.source.openSourceRef(sourceRef, session.userId);
|
|
7733
|
+
return await this.runtime.stateStore.getLongArticleDraft(session.userId, sourceRef, itemUid?.trim() || void 0);
|
|
7734
|
+
}
|
|
7735
|
+
async putLongArticleDraft(draft) {
|
|
7736
|
+
const session = await this.runtime.requireSession();
|
|
7737
|
+
await this.source.openSourceRef(draft.sourceRef, session.userId);
|
|
7738
|
+
const itemUid = draft.itemUid?.trim() || void 0;
|
|
7739
|
+
if (draft.title.length > 100 || draft.textContent.length > 4e4 || draft.durationMillis < 0) throw new ArkmePluginError("long-article-draft-invalid", "长文草稿内容无效", false);
|
|
7740
|
+
await this.runtime.stateStore.putLongArticleDraft(session.userId, {
|
|
7741
|
+
sourceRef: draft.sourceRef,
|
|
7742
|
+
...itemUid === void 0 ? {} : { itemUid },
|
|
7743
|
+
title: draft.title,
|
|
7744
|
+
textContent: draft.textContent,
|
|
7745
|
+
durationMillis: Math.max(0, Math.trunc(draft.durationMillis)),
|
|
7746
|
+
updatedAtMillis: Date.now()
|
|
7747
|
+
});
|
|
7748
|
+
}
|
|
7749
|
+
async removeLongArticleDraft(sourceRef, itemUid) {
|
|
7750
|
+
const session = await this.runtime.requireSession();
|
|
7751
|
+
await this.source.openSourceRef(sourceRef, session.userId);
|
|
7752
|
+
await this.runtime.stateStore.removeLongArticleDraft(session.userId, sourceRef, itemUid?.trim() || void 0);
|
|
7753
|
+
}
|
|
7754
|
+
async cachedSnapshot() {
|
|
7755
|
+
const session = await this.runtime.requireSession();
|
|
7756
|
+
return await this.runtime.stateStore.cachedSnapshot(session.userId);
|
|
7757
|
+
}
|
|
7758
|
+
async queryCached(options) {
|
|
7759
|
+
const session = await this.runtime.requireSession();
|
|
7760
|
+
return await this.runtime.stateStore.queryCached(session.userId, options);
|
|
7761
|
+
}
|
|
7762
|
+
async refreshLatest() {
|
|
7763
|
+
await Promise.all([this.summary(), this.list(50)]);
|
|
7764
|
+
}
|
|
7765
|
+
async refreshSnapshot() {
|
|
7766
|
+
await this.refreshLatest();
|
|
7767
|
+
return await this.cachedSnapshot();
|
|
7768
|
+
}
|
|
7769
|
+
async summary() {
|
|
7770
|
+
const session = await this.runtime.requireSession();
|
|
7771
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/uncategorized/summary", {}, session);
|
|
7772
|
+
const summary = {
|
|
7773
|
+
recordCount: numberValue$17(data.record_count),
|
|
7774
|
+
wordsCount: numberValue$17(data.words_count ?? data.available_text_rune_count),
|
|
7775
|
+
totalSec: numberValue$17(data.total_sec ?? data.available_voice_duration_sec)
|
|
7776
|
+
};
|
|
7777
|
+
await this.runtime.stateStore.cacheSummary(session.userId, summary);
|
|
7778
|
+
return summary;
|
|
7779
|
+
}
|
|
7780
|
+
async list(limit, cursor) {
|
|
7781
|
+
const session = await this.runtime.requireSession();
|
|
7782
|
+
const lockedRecordUids = await this.privacy.lockedRecordUids(session);
|
|
7783
|
+
const normalizedLimit = Math.min(50, Math.max(1, Math.trunc(limit || 30)));
|
|
7784
|
+
let requestCursor = cursor;
|
|
7785
|
+
let hasMore = false;
|
|
7786
|
+
let backendNextCursor;
|
|
7787
|
+
const visibleRawItems = [];
|
|
7788
|
+
for (let pageIndex = 0; pageIndex < MAX_DEFAULT_CATEGORY_FILTER_BACKFILL_PAGES; pageIndex += 1) {
|
|
7789
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/uncategorized/query", {
|
|
7790
|
+
limit: normalizedLimit,
|
|
7791
|
+
...requestCursor === void 0 ? {} : {
|
|
7792
|
+
cursor_send_at: requestCursor.sendAtMillis,
|
|
7793
|
+
cursor_record_uid: requestCursor.recordUid
|
|
7794
|
+
}
|
|
7795
|
+
}, session);
|
|
7796
|
+
const rawPageItems = listValue$17(data.items);
|
|
7797
|
+
const visiblePageItems = rawPageItems.filter((raw) => !isDSHAgentInputRecord(raw) && !arkmePrivacyLockedRecord(raw) && !lockedRecordUids.has(this.recordUid(raw)));
|
|
7798
|
+
visibleRawItems.push(...visiblePageItems);
|
|
7799
|
+
hasMore = data.has_more === true;
|
|
7800
|
+
const nextSendAt = numberValue$17(data.next_cursor_send_at);
|
|
7801
|
+
const nextUid = stringValue$1(data.next_cursor_record_uid);
|
|
7802
|
+
backendNextCursor = nextSendAt > 0 && nextUid !== "" ? {
|
|
7803
|
+
sendAtMillis: nextSendAt,
|
|
7804
|
+
recordUid: nextUid
|
|
7805
|
+
} : void 0;
|
|
7806
|
+
const filteredCount = rawPageItems.length - visiblePageItems.length;
|
|
7807
|
+
if (visibleRawItems.length >= normalizedLimit || !hasMore || backendNextCursor === void 0 || filteredCount === 0) break;
|
|
7808
|
+
requestCursor = backendNextCursor;
|
|
7809
|
+
}
|
|
7810
|
+
const visibleOverflow = visibleRawItems.length > normalizedLimit;
|
|
7811
|
+
const rawItems = visibleRawItems.slice(0, normalizedLimit);
|
|
7812
|
+
const media = await this.media.hydrateRecordMediaPage(rawItems, session);
|
|
7813
|
+
const items = rawItems.map((raw) => {
|
|
7814
|
+
const recordUid = this.recordUid(raw);
|
|
7815
|
+
const displayItems = media.displayItemsByRecordUid.get(recordUid);
|
|
7816
|
+
return this.recordItem(raw, session.userId, {
|
|
7817
|
+
...displayItems === void 0 ? {} : { displayItems },
|
|
7818
|
+
mediaUnavailable: media.unavailableRecordUids.has(recordUid)
|
|
7819
|
+
});
|
|
7820
|
+
}).filter((item) => item !== void 0);
|
|
7821
|
+
const lastVisibleRaw = rawItems.at(-1);
|
|
7822
|
+
const lastVisibleCursor = lastVisibleRaw === void 0 ? void 0 : {
|
|
7823
|
+
sendAtMillis: numberValue$17(objectValue$1(lastVisibleRaw).send_at ?? objectValue$1(objectValue$1(lastVisibleRaw).record_core).send_at),
|
|
7824
|
+
recordUid: this.recordUid(lastVisibleRaw)
|
|
7825
|
+
};
|
|
7826
|
+
const filledRequestedPage = rawItems.length >= normalizedLimit;
|
|
7827
|
+
const nextCursor = lastVisibleCursor !== void 0 && lastVisibleCursor.sendAtMillis > 0 && lastVisibleCursor.recordUid !== "" && (visibleOverflow || filledRequestedPage && hasMore) ? lastVisibleCursor : backendNextCursor;
|
|
7828
|
+
const page = {
|
|
7829
|
+
items,
|
|
7830
|
+
hasMore: hasMore || visibleOverflow,
|
|
7831
|
+
...nextCursor === void 0 ? {} : { nextCursor }
|
|
7832
|
+
};
|
|
7833
|
+
await this.runtime.stateStore.cachePage(session.userId, page, cursor);
|
|
7834
|
+
return page;
|
|
7835
|
+
}
|
|
7836
|
+
async createText(recordUid, textContent, options = {}) {
|
|
7837
|
+
const session = await this.runtime.requireSession();
|
|
7838
|
+
const normalizedUid = recordUid.trim();
|
|
7839
|
+
const normalizedText = textContent.trim();
|
|
7840
|
+
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(normalizedUid)) throw new ArkmePluginError("record-uid-invalid", "写入标识无效,请重试", false);
|
|
7841
|
+
if (normalizedText === "") throw new ArkmePluginError("record-text-empty", "请输入要发给自己的内容", false);
|
|
7842
|
+
if (normalizedText.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("record-text-too-long", `内容不能超过 ${this.runtime.config.maxTextLength} 个字符`, false);
|
|
7843
|
+
const now = Date.now();
|
|
7844
|
+
const recordDurationMillis = Math.max(0, Math.trunc(options.recordDurationMillis ?? 0));
|
|
7845
|
+
const captureContext = normalizedRecordCaptureContext(options.captureContext);
|
|
7846
|
+
const pending = {
|
|
7847
|
+
recordUid: normalizedUid,
|
|
7848
|
+
textContent: normalizedText,
|
|
7849
|
+
createdAtMillis: now,
|
|
7850
|
+
sendAtMillis: now,
|
|
7851
|
+
attempts: 0,
|
|
7852
|
+
...recordDurationMillis === 0 ? {} : { recordDurationMillis },
|
|
7853
|
+
...captureContext === void 0 ? {} : { captureContext }
|
|
7854
|
+
};
|
|
7855
|
+
await this.runtime.stateStore.putPending(session.userId, pending);
|
|
7856
|
+
return await this.sendPending(session, pending);
|
|
7857
|
+
}
|
|
7858
|
+
async createTextForConversation(recordUid, textContent, options = {}) {
|
|
7859
|
+
try {
|
|
7860
|
+
return {
|
|
7861
|
+
...await this.createText(recordUid, textContent, options),
|
|
7862
|
+
localState: "synced"
|
|
7863
|
+
};
|
|
7864
|
+
} catch (error) {
|
|
7865
|
+
const session = await this.runtime.requireSession();
|
|
7866
|
+
const pending = (await this.runtime.stateStore.listPending(session.userId)).find((item) => item.recordUid === recordUid);
|
|
7867
|
+
if (pending === void 0) throw error;
|
|
7868
|
+
return {
|
|
7869
|
+
recordUid,
|
|
7870
|
+
status: 0,
|
|
7871
|
+
localState: "failed",
|
|
7872
|
+
error: pending.lastError ?? safeFailureMessage$4(error)
|
|
7873
|
+
};
|
|
7874
|
+
}
|
|
7875
|
+
}
|
|
7876
|
+
async createDSHAgentInputText(recordUid, textContent, sendAtMillis) {
|
|
7877
|
+
const session = await this.runtime.requireSession();
|
|
7878
|
+
const normalizedUid = recordUid.trim();
|
|
7879
|
+
const normalizedText = textContent.trim();
|
|
7880
|
+
const normalizedSendAt = Math.max(0, Math.trunc(sendAtMillis));
|
|
7881
|
+
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(normalizedUid)) throw new ArkmePluginError("record-uid-invalid", "写入标识无效,请重试", false);
|
|
7882
|
+
if (normalizedText === "") throw new ArkmePluginError("record-text-empty", "请输入要发给自己的内容", false);
|
|
7883
|
+
if (normalizedText.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("record-text-too-long", `内容不能超过 ${this.runtime.config.maxTextLength} 个字符`, false);
|
|
7884
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/dsh-agent-input/create", {
|
|
7885
|
+
record_uid: normalizedUid,
|
|
7886
|
+
template_kind: 1,
|
|
7887
|
+
title: "",
|
|
7888
|
+
text_content: normalizedText,
|
|
7889
|
+
send_at: normalizedSendAt > 0 ? normalizedSendAt : Date.now()
|
|
7890
|
+
}, session, void 0, {
|
|
7891
|
+
scope: this.runtime.requestScope(session.userId),
|
|
7892
|
+
key: `dsh-agent-input:${normalizedUid}`
|
|
7893
|
+
});
|
|
7894
|
+
this.runtime.invalidateScope(this.runtime.requestScope(session.userId));
|
|
7895
|
+
return {
|
|
7896
|
+
recordUid: stringValue$1(data.record_uid) || normalizedUid,
|
|
7897
|
+
status: numberValue$17(data.status)
|
|
7898
|
+
};
|
|
7899
|
+
}
|
|
7900
|
+
async createFileAssetsForConversation(recordUid, textContent, assets) {
|
|
7901
|
+
const session = await this.runtime.requireSession();
|
|
7902
|
+
const normalizedUid = recordUid.trim();
|
|
7903
|
+
const normalizedText = textContent.trim();
|
|
7904
|
+
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(normalizedUid)) throw new ArkmePluginError("record-uid-invalid", "写入标识无效,请重试", false);
|
|
7905
|
+
if (assets.length === 0 || assets.length > 20 || normalizedText.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("record-file-assets-invalid", "附件内容为空、过长或数量超限", false);
|
|
7906
|
+
for (const asset of assets) if (!/^[A-Za-z0-9._:-]{8,256}$/.test(asset.fileAssetUid) || asset.fileName.trim() === "" || asset.fileName.length > 255 || !Number.isSafeInteger(asset.size) || asset.size <= 0 || ![
|
|
7907
|
+
1,
|
|
7908
|
+
2,
|
|
7909
|
+
3,
|
|
7910
|
+
4
|
|
7911
|
+
].includes(asset.fileKind)) throw new ArkmePluginError("record-file-asset-invalid", "附件资产参数无效", false);
|
|
7912
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/create", {
|
|
7913
|
+
record_uid: normalizedUid,
|
|
7914
|
+
template_kind: 2,
|
|
7915
|
+
display_kind: 0,
|
|
7916
|
+
title: "",
|
|
7917
|
+
text_content: normalizedText,
|
|
7918
|
+
content_payload: {
|
|
7919
|
+
payload_kind: 2,
|
|
7920
|
+
schema_version: 1,
|
|
7921
|
+
text_state: normalizedText === "" ? 3 : 1,
|
|
7922
|
+
media_refs: assets.map((asset, index) => ({
|
|
7923
|
+
file_asset_uid: asset.fileAssetUid,
|
|
7924
|
+
content_file_role: 1,
|
|
7925
|
+
render_role: 1,
|
|
7926
|
+
sort_order: index,
|
|
7927
|
+
file_name: asset.fileName
|
|
7928
|
+
}))
|
|
7929
|
+
},
|
|
7930
|
+
send_at: Date.now()
|
|
7931
|
+
}, session);
|
|
7932
|
+
return {
|
|
7933
|
+
recordUid: stringValue$1(data.record_uid).trim() || normalizedUid,
|
|
7934
|
+
status: numberValue$17(data.status)
|
|
7935
|
+
};
|
|
7936
|
+
}
|
|
7937
|
+
async pendingWrites() {
|
|
7938
|
+
const session = await this.runtime.requireSession();
|
|
7939
|
+
return await this.runtime.stateStore.listPending(session.userId);
|
|
7940
|
+
}
|
|
7941
|
+
async retryPending(recordUid) {
|
|
7942
|
+
const session = await this.runtime.requireSession();
|
|
7943
|
+
const pending = (await this.runtime.stateStore.listPending(session.userId)).find((item) => item.recordUid === recordUid);
|
|
7944
|
+
if (pending === void 0) throw new ArkmePluginError("outbox-entry-not-found", "待重试内容不存在", false, 404);
|
|
7945
|
+
return await this.sendPending(session, pending);
|
|
7946
|
+
}
|
|
7947
|
+
async sendPending(session, pending) {
|
|
7948
|
+
try {
|
|
7949
|
+
const captureContext = pending.captureContext === void 0 ? void 0 : arkmeRecordCaptureContextPayload(pending.captureContext);
|
|
7950
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/create", {
|
|
7951
|
+
record_uid: pending.recordUid,
|
|
7952
|
+
template_kind: 1,
|
|
7953
|
+
title: "",
|
|
7954
|
+
text_content: pending.textContent,
|
|
7955
|
+
...Math.max(0, Math.trunc(pending.recordDurationMillis ?? 0)) === 0 ? {} : { record_duration_millis: Math.max(0, Math.trunc(pending.recordDurationMillis ?? 0)) },
|
|
7956
|
+
...captureContext === void 0 || Object.keys(captureContext).length === 0 ? {} : { capture_context: captureContext },
|
|
7957
|
+
send_at: pending.sendAtMillis
|
|
7958
|
+
}, session);
|
|
7959
|
+
const result = {
|
|
7960
|
+
recordUid: stringValue$1(data.record_uid) || pending.recordUid,
|
|
7961
|
+
status: numberValue$17(data.status)
|
|
7962
|
+
};
|
|
7963
|
+
await this.runtime.stateStore.markSynced(session.userId, pending.recordUid, result.status);
|
|
7964
|
+
return result;
|
|
7965
|
+
} catch (error) {
|
|
7966
|
+
await this.runtime.stateStore.markAttempt(session.userId, pending.recordUid, safeFailureMessage$4(error));
|
|
7967
|
+
throw error;
|
|
7968
|
+
}
|
|
7969
|
+
}
|
|
7970
|
+
recordUid(raw) {
|
|
7971
|
+
const item = objectValue$1(raw);
|
|
7972
|
+
return stringValue$1(item.record_uid ?? objectValue$1(item.record_core).record_uid).trim();
|
|
7973
|
+
}
|
|
7974
|
+
recordTimelineItem(item) {
|
|
7975
|
+
return {
|
|
7976
|
+
itemUid: item.recordUid,
|
|
7977
|
+
senderName: "我",
|
|
7978
|
+
isMe: true,
|
|
7979
|
+
sendAtMillis: item.sendAtMillis,
|
|
7980
|
+
title: item.title,
|
|
7981
|
+
textContent: item.textContent,
|
|
7982
|
+
status: item.status,
|
|
7983
|
+
templateKind: item.templateKind,
|
|
7984
|
+
version: item.version,
|
|
7985
|
+
...item.displayKind === void 0 ? {} : { displayKind: item.displayKind },
|
|
7986
|
+
...item.contentBlocks === void 0 ? {} : { contentBlocks: item.contentBlocks },
|
|
7987
|
+
...item.mediaUnavailable === true ? { mediaUnavailable: true } : {}
|
|
7988
|
+
};
|
|
7989
|
+
}
|
|
7990
|
+
recordTimelineItemFromRaw(raw, userId, options = {}) {
|
|
7991
|
+
const item = objectValue$1(raw);
|
|
7992
|
+
const core = objectValue$1(item.record_core);
|
|
7993
|
+
return {
|
|
7994
|
+
itemUid: stringValue$1(item.record_uid ?? core.record_uid).trim(),
|
|
7995
|
+
senderName: stringValue$1(item.nickname).trim() || "我",
|
|
7996
|
+
isMe: options.isMe ?? numberValue$17(item.creator_user_id ?? item.owner_user_id ?? core.creator_user_id ?? core.owner_user_id) === userId,
|
|
7997
|
+
sendAtMillis: numberValue$17(item.send_at ?? core.send_at),
|
|
7998
|
+
title: stringValue$1(item.title ?? core.title),
|
|
7999
|
+
textContent: stringValue$1(item.text_content ?? core.text_content),
|
|
8000
|
+
status: numberValue$17(item.status ?? core.status),
|
|
8001
|
+
templateKind: numberValue$17(item.template_kind ?? core.template_kind),
|
|
8002
|
+
displayKind: numberValue$17(item.display_kind ?? core.display_kind),
|
|
8003
|
+
version: numberValue$17(item.version ?? core.version),
|
|
8004
|
+
updateAtMillis: numberValue$17(item.update_at ?? core.update_at),
|
|
8005
|
+
recordDurationMillis: numberValue$17(item.record_duration_millis ?? core.record_duration_millis),
|
|
8006
|
+
editDurationMillis: numberValue$17(item.edit_duration_millis ?? core.edit_duration_millis),
|
|
8007
|
+
contentBlocks: this.media.richContentBlocks(raw, userId, options.displayItems),
|
|
8008
|
+
...options.selfTopic === void 0 ? {} : { selfTopic: options.selfTopic },
|
|
8009
|
+
...options.mediaUnavailable === true ? { mediaUnavailable: true } : {}
|
|
8010
|
+
};
|
|
8011
|
+
}
|
|
8012
|
+
recordItem(raw, userId, options = {}) {
|
|
8013
|
+
const item = objectValue$1(raw);
|
|
8014
|
+
const core = objectValue$1(item.record_core);
|
|
8015
|
+
const recordUid = stringValue$1(item.record_uid ?? core.record_uid).trim();
|
|
8016
|
+
if (recordUid === "") return void 0;
|
|
8017
|
+
return {
|
|
8018
|
+
recordUid,
|
|
8019
|
+
sendAtMillis: numberValue$17(item.send_at ?? core.send_at),
|
|
8020
|
+
title: stringValue$1(core.title),
|
|
8021
|
+
textContent: stringValue$1(core.text_content),
|
|
8022
|
+
templateKind: numberValue$17(core.template_kind),
|
|
8023
|
+
status: numberValue$17(core.status),
|
|
8024
|
+
version: numberValue$17(core.version),
|
|
8025
|
+
creationSource: recordCreationSource(raw),
|
|
8026
|
+
displayKind: numberValue$17(item.display_kind ?? core.display_kind),
|
|
8027
|
+
...userId === void 0 ? {} : { contentBlocks: this.media.richContentBlocks(raw, userId, options.displayItems) },
|
|
8028
|
+
...options.mediaUnavailable === true ? { mediaUnavailable: true } : {}
|
|
8029
|
+
};
|
|
8030
|
+
}
|
|
8031
|
+
isDSHAgentInput(raw) {
|
|
8032
|
+
return isDSHAgentInputRecord(raw);
|
|
8033
|
+
}
|
|
8034
|
+
isPrivacyLocked(raw) {
|
|
8035
|
+
return arkmePrivacyLockedRecord(raw);
|
|
8036
|
+
}
|
|
8037
|
+
async syncHistory(maxPages = 20, signal) {
|
|
8038
|
+
const pageCap = Math.min(20, Math.max(1, Math.trunc(maxPages)));
|
|
8039
|
+
await this.refreshLatest();
|
|
8040
|
+
let snapshot = await this.cachedSnapshot();
|
|
8041
|
+
let pages = 0;
|
|
8042
|
+
while (snapshot.hasMore && snapshot.nextCursor !== void 0 && pages < pageCap) {
|
|
8043
|
+
if (signal?.aborted === true) throw new Error("Arkme历史同步已取消");
|
|
8044
|
+
await this.list(50, snapshot.nextCursor);
|
|
8045
|
+
pages += 1;
|
|
8046
|
+
snapshot = await this.cachedSnapshot();
|
|
8047
|
+
}
|
|
8048
|
+
return {
|
|
8049
|
+
pages,
|
|
8050
|
+
complete: !snapshot.hasMore
|
|
8051
|
+
};
|
|
8052
|
+
}
|
|
8053
|
+
};
|
|
8054
|
+
//#endregion
|
|
7604
8055
|
//#region src/services/chat-service.ts
|
|
7605
8056
|
const OFFICIAL_AUTHOR_USER_ID = 11;
|
|
7606
8057
|
const OFFICIAL_AUTHOR_FALLBACK_DISPLAY_NAME = "即我作者";
|
|
7607
8058
|
const MAX_MESSAGE_COPY_LINK_ITEMS = 100;
|
|
7608
8059
|
const RECORD_UID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8060
|
+
const CHAT_MEMBER_REF_PREFIX = "arkme-chat-member-v1";
|
|
8061
|
+
const CHAT_HUMAN_MENTION_REF_PREFIX = "arkme-chat-human-mention-v1";
|
|
7609
8062
|
function numberValue$16(value) {
|
|
7610
8063
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
7611
8064
|
}
|
|
8065
|
+
function finiteNumberValue(value) {
|
|
8066
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
8067
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
8068
|
+
const parsed = Number(value);
|
|
8069
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
8070
|
+
}
|
|
8071
|
+
}
|
|
8072
|
+
function positiveNumberValue$1(...values) {
|
|
8073
|
+
for (const value of values) {
|
|
8074
|
+
const parsed = finiteNumberValue(value);
|
|
8075
|
+
if (parsed !== void 0 && parsed > 0) return parsed;
|
|
8076
|
+
}
|
|
8077
|
+
}
|
|
8078
|
+
function nonNegativeNumberValue(...values) {
|
|
8079
|
+
for (const value of values) {
|
|
8080
|
+
const parsed = finiteNumberValue(value);
|
|
8081
|
+
if (parsed !== void 0 && parsed >= 0) return parsed;
|
|
8082
|
+
}
|
|
8083
|
+
}
|
|
7612
8084
|
function booleanValue$8(value) {
|
|
7613
8085
|
return value === true;
|
|
7614
8086
|
}
|
|
8087
|
+
function timelineCaptureContext(payload) {
|
|
8088
|
+
const raw = objectValue$1(payload.capture_context ?? payload.captureContext);
|
|
8089
|
+
const clientName = stringValue$1(raw.client_name ?? raw.clientName ?? payload.client_name ?? payload.clientName ?? payload.device_name ?? payload.deviceName).trim();
|
|
8090
|
+
const networkName = stringValue$1(raw.network_name ?? raw.networkName ?? payload.network_name ?? payload.networkName ?? payload.network).trim();
|
|
8091
|
+
const electricity = objectValue$1(payload.electricity);
|
|
8092
|
+
const electricValue = finiteNumberValue(raw.electric ?? payload.electric ?? electricity.electric);
|
|
8093
|
+
const electric = electricValue === void 0 ? void 0 : Math.trunc(electricValue);
|
|
8094
|
+
const charge = Math.trunc(numberValue$16(raw.charge ?? payload.charge ?? electricity.charge));
|
|
8095
|
+
const context = {
|
|
8096
|
+
...clientName === "" ? {} : { clientName },
|
|
8097
|
+
...networkName === "" ? {} : { networkName },
|
|
8098
|
+
...electric === void 0 || electric < 0 || electric > 100 ? {} : { electric },
|
|
8099
|
+
...charge < 1 || charge > 3 ? {} : { charge }
|
|
8100
|
+
};
|
|
8101
|
+
return Object.keys(context).length === 0 ? void 0 : context;
|
|
8102
|
+
}
|
|
8103
|
+
function epochMillis(value) {
|
|
8104
|
+
const parsed = finiteNumberValue(value);
|
|
8105
|
+
if (parsed === void 0 || parsed <= 0) return void 0;
|
|
8106
|
+
return Math.trunc(parsed < 1e11 ? parsed * 1e3 : parsed);
|
|
8107
|
+
}
|
|
8108
|
+
/**
|
|
8109
|
+
* Record lifecycle timestamps are canonical fields of the record itself.
|
|
8110
|
+
* Payload and extra metadata may carry stale (or zero) copies, so they can
|
|
8111
|
+
* only be used as a final fallback. This matches the Flutter record parser,
|
|
8112
|
+
* which creates the Record timestamp model from record_core first.
|
|
8113
|
+
*/
|
|
8114
|
+
function firstRecordEpochMillis(sources, keys) {
|
|
8115
|
+
for (const source of sources) for (const key of keys) {
|
|
8116
|
+
const value = epochMillis(source[key]);
|
|
8117
|
+
if (value !== void 0) return value;
|
|
8118
|
+
}
|
|
8119
|
+
}
|
|
8120
|
+
function firstSnapshotText(...values) {
|
|
8121
|
+
for (const value of values) {
|
|
8122
|
+
const text = stringValue$1(value).trim();
|
|
8123
|
+
if (text !== "") return text;
|
|
8124
|
+
}
|
|
8125
|
+
}
|
|
8126
|
+
function snapshotDateLabel(value) {
|
|
8127
|
+
if (value === void 0) return void 0;
|
|
8128
|
+
const date = new Date(value);
|
|
8129
|
+
if (Number.isNaN(date.getTime())) return void 0;
|
|
8130
|
+
return new Intl.DateTimeFormat("zh-CN", {
|
|
8131
|
+
year: "numeric",
|
|
8132
|
+
month: "2-digit",
|
|
8133
|
+
day: "2-digit"
|
|
8134
|
+
}).format(date);
|
|
8135
|
+
}
|
|
8136
|
+
function snapshotMovement(value) {
|
|
8137
|
+
const rawSpeed = value.speed ?? value.speed_mps ?? value.speedMetersPerSecond;
|
|
8138
|
+
const speed = numberValue$16(rawSpeed);
|
|
8139
|
+
if (typeof rawSpeed === "number" && Number.isFinite(rawSpeed)) {
|
|
8140
|
+
const kmh = Math.round(speed * 3.6);
|
|
8141
|
+
return kmh <= 2 ? "静止" : kmh <= 5 ? `缓慢移动(${String(kmh)}km/h)` : kmh <= 60 ? `移动(${String(kmh)}km/h)` : `高速移动(${String(kmh)}km/h)`;
|
|
8142
|
+
}
|
|
8143
|
+
if (typeof value.activity !== "number" || !Number.isFinite(value.activity)) return void 0;
|
|
8144
|
+
const activity = Math.trunc(value.activity);
|
|
8145
|
+
return activity === 0 ? "静止" : activity === 1 ? "步行" : activity === 2 ? "跑步" : activity === 3 ? "骑行" : activity === 4 ? "驾车" : void 0;
|
|
8146
|
+
}
|
|
8147
|
+
function snapshotLocationCapture(value) {
|
|
8148
|
+
const latitude = finiteNumberValue(value.lat ?? value.latitude);
|
|
8149
|
+
const longitude = finiteNumberValue(value.lon ?? value.lng ?? value.longitude);
|
|
8150
|
+
if (latitude === void 0 || longitude === void 0 || latitude === 0 && longitude === 0) return void 0;
|
|
8151
|
+
const altitudeMeters = nonNegativeNumberValue(value.alt ?? value.altitude ?? value.altitude_meters);
|
|
8152
|
+
const accuracyMeters = nonNegativeNumberValue(value.accuracy ?? value.accuracy_meters ?? value.accuracyMeters);
|
|
8153
|
+
const speedMetersPerSecond = nonNegativeNumberValue(value.speed ?? value.speed_mps ?? value.speedMetersPerSecond);
|
|
8154
|
+
return {
|
|
8155
|
+
latitude,
|
|
8156
|
+
longitude,
|
|
8157
|
+
capturedAtMillis: epochMillis(value.captured_at ?? value.capturedAt) ?? Date.now(),
|
|
8158
|
+
...accuracyMeters === void 0 ? {} : { accuracyMeters },
|
|
8159
|
+
...altitudeMeters === void 0 ? {} : { altitudeMeters },
|
|
8160
|
+
...speedMetersPerSecond === void 0 ? {} : { speedMetersPerSecond }
|
|
8161
|
+
};
|
|
8162
|
+
}
|
|
8163
|
+
function snapshotWeatherText(...values) {
|
|
8164
|
+
for (const value of values) {
|
|
8165
|
+
const direct = stringValue$1(value).trim();
|
|
8166
|
+
if (direct !== "") return direct;
|
|
8167
|
+
const weather = objectValue$1(value);
|
|
8168
|
+
if (Object.keys(weather).length === 0) continue;
|
|
8169
|
+
const temperature = finiteNumberValue(weather.temp ?? weather.temperature);
|
|
8170
|
+
const condition = firstSnapshotText(weather.weather, weather.weatherText, weather.weather_text, weather.condition_ch, weather.conditionCh, weather.condition);
|
|
8171
|
+
if (temperature !== void 0 || condition !== void 0) return `${temperature === void 0 ? "" : `${String(Math.round(temperature))}°`}${temperature === void 0 || condition === void 0 ? "" : " "}${condition ?? ""}`.trim();
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8174
|
+
function snapshotLocationContext(value) {
|
|
8175
|
+
const root = objectValue$1(value);
|
|
8176
|
+
const nested = objectValue$1(root.data);
|
|
8177
|
+
const hasContext = (candidate) => [
|
|
8178
|
+
candidate.location,
|
|
8179
|
+
candidate.position_detail,
|
|
8180
|
+
candidate.positionDetail,
|
|
8181
|
+
candidate.weather
|
|
8182
|
+
].some((entry) => Object.keys(parsedObject(entry)).length > 0 || stringValue$1(entry).trim() !== "");
|
|
8183
|
+
return hasContext(root) || !hasContext(nested) ? root : nested;
|
|
8184
|
+
}
|
|
8185
|
+
/**
|
|
8186
|
+
* `/records/detail` and `/records/location/context/get` intentionally split
|
|
8187
|
+
* their metadata. Flutter overlays the latter onto the former, retaining
|
|
8188
|
+
* every existing location field while allowing its resolved weather and
|
|
8189
|
+
* address to win. Keep that same shape before projecting the dialog detail.
|
|
8190
|
+
*/
|
|
8191
|
+
function mergeSnapshotLocationContext(raw, contextValue) {
|
|
8192
|
+
const context = snapshotLocationContext(contextValue);
|
|
8193
|
+
if (Object.keys(context).length === 0) return raw;
|
|
8194
|
+
const location = {
|
|
8195
|
+
...parsedObject(raw.location),
|
|
8196
|
+
...parsedObject(raw.location_detail),
|
|
8197
|
+
...parsedObject(context.location),
|
|
8198
|
+
...parsedObject(context.location_detail)
|
|
8199
|
+
};
|
|
8200
|
+
const position = {
|
|
8201
|
+
...parsedObject(raw.position_detail),
|
|
8202
|
+
...parsedObject(raw.positionDetail),
|
|
8203
|
+
...parsedObject(context.position_detail),
|
|
8204
|
+
...parsedObject(context.positionDetail)
|
|
8205
|
+
};
|
|
8206
|
+
const weather = context.weather ?? context.weather_text ?? context.weatherText ?? raw.weather;
|
|
8207
|
+
return {
|
|
8208
|
+
...raw,
|
|
8209
|
+
...Object.keys(location).length === 0 ? {} : { location },
|
|
8210
|
+
...Object.keys(position).length === 0 ? {} : { position_detail: position },
|
|
8211
|
+
...weather === void 0 ? {} : { weather }
|
|
8212
|
+
};
|
|
8213
|
+
}
|
|
8214
|
+
function snapshotDetailFromChatRaw(raw, fallback) {
|
|
8215
|
+
const relation = objectValue$1(raw.relation);
|
|
8216
|
+
const recordCore = objectValue$1(raw.record_core ?? raw.recordCore ?? raw.record ?? raw);
|
|
8217
|
+
const nestedRecord = objectValue$1(raw.record);
|
|
8218
|
+
const record = {
|
|
8219
|
+
...recordCore,
|
|
8220
|
+
...nestedRecord
|
|
8221
|
+
};
|
|
8222
|
+
const rootPayload = {
|
|
8223
|
+
...parsedObject(raw.payload),
|
|
8224
|
+
...parsedObject(raw.content_payload),
|
|
8225
|
+
...parsedObject(raw.contentPayload),
|
|
8226
|
+
...parsedObject(raw.record_payload),
|
|
8227
|
+
...parsedObject(raw.recordPayload)
|
|
8228
|
+
};
|
|
8229
|
+
const recordPayload = {
|
|
8230
|
+
...parsedObject(record.payload),
|
|
8231
|
+
...parsedObject(record.content_payload),
|
|
8232
|
+
...parsedObject(record.contentPayload),
|
|
8233
|
+
...parsedObject(record.record_payload),
|
|
8234
|
+
...parsedObject(record.recordPayload)
|
|
8235
|
+
};
|
|
8236
|
+
const extra = {
|
|
8237
|
+
...parsedObject(raw.extra),
|
|
8238
|
+
...parsedObject(raw.record_extra),
|
|
8239
|
+
...parsedObject(raw.recordExtra),
|
|
8240
|
+
...parsedObject(raw.e),
|
|
8241
|
+
...parsedObject(raw.i)
|
|
8242
|
+
};
|
|
8243
|
+
const recordExtra = {
|
|
8244
|
+
...parsedObject(record.extra),
|
|
8245
|
+
...parsedObject(record.record_extra),
|
|
8246
|
+
...parsedObject(record.recordExtra),
|
|
8247
|
+
...parsedObject(record.e),
|
|
8248
|
+
...parsedObject(record.i)
|
|
8249
|
+
};
|
|
8250
|
+
const payload = {
|
|
8251
|
+
...extra,
|
|
8252
|
+
...recordExtra,
|
|
8253
|
+
...rootPayload,
|
|
8254
|
+
...recordPayload
|
|
8255
|
+
};
|
|
8256
|
+
const position = {
|
|
8257
|
+
...parsedObject(payload.position_detail),
|
|
8258
|
+
...parsedObject(payload.positionDetail),
|
|
8259
|
+
...parsedObject(record.position_detail),
|
|
8260
|
+
...parsedObject(record.positionDetail),
|
|
8261
|
+
...parsedObject(raw.position_detail),
|
|
8262
|
+
...parsedObject(raw.positionDetail)
|
|
8263
|
+
};
|
|
8264
|
+
const location = {
|
|
8265
|
+
...parsedObject(payload.location),
|
|
8266
|
+
...parsedObject(record.location),
|
|
8267
|
+
...parsedObject(raw.location)
|
|
8268
|
+
};
|
|
8269
|
+
const values = {
|
|
8270
|
+
...raw,
|
|
8271
|
+
...record,
|
|
8272
|
+
...payload
|
|
8273
|
+
};
|
|
8274
|
+
const recordDurationMillis = positiveNumberValue$1(values.record_duration_millis, values.recordDurationMillis, values.cost_mill_sec, values.costMillSec);
|
|
8275
|
+
const editDurationMillis = positiveNumberValue$1(values.edit_duration_millis, values.editDurationMillis, values.incr_cost_mill_sec, values.incrCostMillSec);
|
|
8276
|
+
const lifecycleSources = [
|
|
8277
|
+
recordCore,
|
|
8278
|
+
nestedRecord,
|
|
8279
|
+
raw,
|
|
8280
|
+
payload
|
|
8281
|
+
];
|
|
8282
|
+
const startAtMillis = firstRecordEpochMillis(lifecycleSources, [
|
|
8283
|
+
"create_at",
|
|
8284
|
+
"created_at",
|
|
8285
|
+
"createAt",
|
|
8286
|
+
"createdAt",
|
|
8287
|
+
"create_time",
|
|
8288
|
+
"createTime",
|
|
8289
|
+
"create_time_stamp",
|
|
8290
|
+
"createTimeStamp",
|
|
8291
|
+
"create_timestamp",
|
|
8292
|
+
"createTimestamp",
|
|
8293
|
+
"create_at_ms",
|
|
8294
|
+
"createAtMillis",
|
|
8295
|
+
"created_at_ms",
|
|
8296
|
+
"createdAtMillis",
|
|
8297
|
+
"send_at",
|
|
8298
|
+
"sendAt",
|
|
8299
|
+
"send_time",
|
|
8300
|
+
"sendTime",
|
|
8301
|
+
"send_time_stamp",
|
|
8302
|
+
"sendTimeStamp",
|
|
8303
|
+
"send_timestamp",
|
|
8304
|
+
"sendTimestamp",
|
|
8305
|
+
"send_at_ms",
|
|
8306
|
+
"sendAtMillis"
|
|
8307
|
+
]) ?? epochMillis(relation.attach_at ?? relation.attachAt);
|
|
8308
|
+
const sendAtMillis = firstRecordEpochMillis(lifecycleSources, [
|
|
8309
|
+
"send_at",
|
|
8310
|
+
"sendAt",
|
|
8311
|
+
"send_time",
|
|
8312
|
+
"sendTime",
|
|
8313
|
+
"send_time_stamp",
|
|
8314
|
+
"sendTimeStamp",
|
|
8315
|
+
"send_timestamp",
|
|
8316
|
+
"sendTimestamp",
|
|
8317
|
+
"send_at_ms",
|
|
8318
|
+
"sendAtMillis"
|
|
8319
|
+
]) ?? epochMillis(relation.attach_at ?? relation.attachAt) ?? epochMillis(fallback.sendAtMillis);
|
|
8320
|
+
const updatedAtMillis = firstRecordEpochMillis(lifecycleSources, [
|
|
8321
|
+
"update_at",
|
|
8322
|
+
"updated_at",
|
|
8323
|
+
"updateAt",
|
|
8324
|
+
"updatedAt",
|
|
8325
|
+
"update_time_stamp",
|
|
8326
|
+
"updateTimeStamp",
|
|
8327
|
+
"update_timestamp",
|
|
8328
|
+
"updateTimestamp",
|
|
8329
|
+
"update_at_ms",
|
|
8330
|
+
"updateAtMillis"
|
|
8331
|
+
]);
|
|
8332
|
+
const completeAtMillis = updatedAtMillis !== void 0 && updatedAtMillis > (sendAtMillis ?? 0) ? updatedAtMillis : sendAtMillis;
|
|
8333
|
+
const syncedAtMillis = firstRecordEpochMillis(lifecycleSources, [
|
|
8334
|
+
"upload_at",
|
|
8335
|
+
"uploadAt",
|
|
8336
|
+
"upload_timestamp",
|
|
8337
|
+
"uploadTimeStamp",
|
|
8338
|
+
"upload_time_stamp_v2",
|
|
8339
|
+
"uploadTimeStampV2",
|
|
8340
|
+
"upload_at_v2",
|
|
8341
|
+
"uploadAtV2",
|
|
8342
|
+
"upload_at_ms",
|
|
8343
|
+
"uploadAtMillis"
|
|
8344
|
+
]);
|
|
8345
|
+
const captureContext = timelineCaptureContext(values);
|
|
8346
|
+
const locationCapture = snapshotLocationCapture({
|
|
8347
|
+
...location,
|
|
8348
|
+
...position,
|
|
8349
|
+
...objectValue$1(values.position)
|
|
8350
|
+
});
|
|
8351
|
+
const locationLabel = firstSnapshotText(position.poi, position.poi_name, position.poiName, position.address, position.road, location.poi_name, location.poiName, location.address, location.name);
|
|
8352
|
+
const weather = snapshotWeatherText(position.weather, position.weatherText, location.weather, values.weather);
|
|
8353
|
+
const altitudeMeters = nonNegativeNumberValue(location.altitude, location.alt, position.altitude, position.alt);
|
|
8354
|
+
const movement = snapshotMovement({
|
|
8355
|
+
...values,
|
|
8356
|
+
...location,
|
|
8357
|
+
...position
|
|
8358
|
+
});
|
|
8359
|
+
const backgroundFiles = [
|
|
8360
|
+
...listValue$16(values.file_assets),
|
|
8361
|
+
...listValue$16(values.fileAssets),
|
|
8362
|
+
...listValue$16(values.media_items),
|
|
8363
|
+
...listValue$16(values.mediaItems),
|
|
8364
|
+
...listValue$16(values.media_refs),
|
|
8365
|
+
...listValue$16(values.mediaRefs),
|
|
8366
|
+
...listValue$16(values.media_display_items),
|
|
8367
|
+
...listValue$16(values.mediaDisplayItems),
|
|
8368
|
+
...listValue$16(values.files),
|
|
8369
|
+
...listValue$16(values.attachments)
|
|
8370
|
+
].map(objectValue$1);
|
|
8371
|
+
const backgroundSound = backgroundFiles.some((file) => Math.trunc(numberValue$16(file.content_file_role ?? file.contentFileRole)) === 4) || backgroundFiles.some((file) => Math.trunc(numberValue$16(file.binding_type ?? file.bindingType)) === 4) || listValue$16(values.background_sound_amplitudes ?? values.backgroundSoundAmplitudes).length > 0 || listValue$16(parsedObject(values.background_sound ?? values.backgroundSound).amplitudes).length > 0 ? "available" : values.background_sound_enabled === false || values.backgroundSoundEnabled === false ? "disabled" : "not-recorded";
|
|
8372
|
+
const status = numberValue$16(values.status);
|
|
8373
|
+
const syncState = status === 2 ? "syncing" : status < 0 ? "failed" : syncedAtMillis !== void 0 || status === 1 ? "synced" : "not-synced";
|
|
8374
|
+
const belongDate = snapshotDateLabel(startAtMillis ?? completeAtMillis);
|
|
8375
|
+
return {
|
|
8376
|
+
itemUid: firstSnapshotText(relation.record_uid, values.record_uid, raw.record_uid) ?? fallback.itemUid,
|
|
8377
|
+
textContent: firstSnapshotText(record.text_content, record.textContent, values.text_content, values.textContent) ?? fallback.textContent,
|
|
8378
|
+
...recordDurationMillis === void 0 ? {} : { recordDurationMillis },
|
|
8379
|
+
...editDurationMillis === void 0 ? {} : { editDurationMillis },
|
|
8380
|
+
...numberValue$16(values.view_times ?? values.viewTimes) > 0 ? { viewTimes: Math.trunc(numberValue$16(values.view_times ?? values.viewTimes)) } : {},
|
|
8381
|
+
...numberValue$16(values.share_times ?? values.shareTimes) > 0 ? { shareTimes: Math.trunc(numberValue$16(values.share_times ?? values.shareTimes)) } : {},
|
|
8382
|
+
...captureContext === void 0 ? {} : { captureContext },
|
|
8383
|
+
backgroundSound,
|
|
8384
|
+
...locationLabel === void 0 ? {} : { locationLabel },
|
|
8385
|
+
...weather === void 0 ? {} : { weather },
|
|
8386
|
+
...altitudeMeters === void 0 ? {} : { altitudeMeters },
|
|
8387
|
+
...movement === void 0 ? {} : { movement },
|
|
8388
|
+
...belongDate === void 0 ? {} : { belongDate },
|
|
8389
|
+
...startAtMillis === void 0 ? {} : { startAtMillis },
|
|
8390
|
+
...completeAtMillis === void 0 ? {} : { completeAtMillis },
|
|
8391
|
+
...syncedAtMillis === void 0 ? {} : { syncedAtMillis },
|
|
8392
|
+
syncState,
|
|
8393
|
+
...locationCapture === void 0 ? {} : { locationCapture }
|
|
8394
|
+
};
|
|
8395
|
+
}
|
|
7615
8396
|
function favoriteStickerPersistenceItem(item) {
|
|
7616
8397
|
return {
|
|
7617
8398
|
file_asset_uid: stringValue$1(item.file_asset_uid).trim(),
|
|
@@ -7642,7 +8423,7 @@ function chatMemberStatus$1(value) {
|
|
|
7642
8423
|
if (value === "removed" || value === 3) return "removed";
|
|
7643
8424
|
return "unknown";
|
|
7644
8425
|
}
|
|
7645
|
-
function integerLikeValue
|
|
8426
|
+
function integerLikeValue(value) {
|
|
7646
8427
|
if (typeof value === "number" && Number.isFinite(value)) return Math.trunc(value);
|
|
7647
8428
|
if (typeof value === "string" && value.trim() !== "") {
|
|
7648
8429
|
const parsed = Number(value.trim());
|
|
@@ -7650,24 +8431,50 @@ function integerLikeValue$1(value) {
|
|
|
7650
8431
|
}
|
|
7651
8432
|
return 0;
|
|
7652
8433
|
}
|
|
8434
|
+
function chatRecordOwnerUserId(relation, record, payload, senderUserId) {
|
|
8435
|
+
const candidates = [
|
|
8436
|
+
relation.record_owner_user_id,
|
|
8437
|
+
relation.recordOwnerUserId,
|
|
8438
|
+
relation.owner_user_id,
|
|
8439
|
+
relation.ownerUserId,
|
|
8440
|
+
record.record_owner_user_id,
|
|
8441
|
+
record.recordOwnerUserId,
|
|
8442
|
+
record.owner_user_id,
|
|
8443
|
+
record.ownerUserId,
|
|
8444
|
+
record.user_id,
|
|
8445
|
+
record.userId,
|
|
8446
|
+
payload.record_owner_user_id,
|
|
8447
|
+
payload.recordOwnerUserId,
|
|
8448
|
+
payload.owner_user_id,
|
|
8449
|
+
payload.ownerUserId,
|
|
8450
|
+
payload.user_id,
|
|
8451
|
+
payload.userId,
|
|
8452
|
+
senderUserId
|
|
8453
|
+
];
|
|
8454
|
+
for (const candidate of candidates) {
|
|
8455
|
+
const userId = integerLikeValue(candidate);
|
|
8456
|
+
if (userId > 0) return userId;
|
|
8457
|
+
}
|
|
8458
|
+
return 0;
|
|
8459
|
+
}
|
|
7653
8460
|
function epochMillisValue(value) {
|
|
7654
|
-
const timestamp = integerLikeValue
|
|
8461
|
+
const timestamp = integerLikeValue(value);
|
|
7655
8462
|
return timestamp > 0 && timestamp < 1e11 ? timestamp * 1e3 : timestamp;
|
|
7656
8463
|
}
|
|
7657
8464
|
function messageCopyLinkMediaItemFromData(value) {
|
|
7658
8465
|
const data = objectValue$1(value);
|
|
7659
8466
|
return {
|
|
7660
|
-
fileKind: integerLikeValue
|
|
8467
|
+
fileKind: integerLikeValue(data.file_kind),
|
|
7661
8468
|
fileName: stringValue$1(data.file_name),
|
|
7662
|
-
size: Math.max(0, integerLikeValue
|
|
8469
|
+
size: Math.max(0, integerLikeValue(data.size))
|
|
7663
8470
|
};
|
|
7664
8471
|
}
|
|
7665
8472
|
function messageCopyLinkStructuredContentFromData(value) {
|
|
7666
8473
|
const data = objectValue$1(value);
|
|
7667
8474
|
if (Object.keys(data).length === 0) return void 0;
|
|
7668
8475
|
return {
|
|
7669
|
-
structuredKind: integerLikeValue
|
|
7670
|
-
durationMillis: Math.max(0, integerLikeValue
|
|
8476
|
+
structuredKind: integerLikeValue(data.structured_kind),
|
|
8477
|
+
durationMillis: Math.max(0, integerLikeValue(data.duration_millis))
|
|
7671
8478
|
};
|
|
7672
8479
|
}
|
|
7673
8480
|
function messageCopyLinkSnapshotItemFromData(value) {
|
|
@@ -7682,9 +8489,9 @@ function messageCopyLinkSnapshotItemFromData(value) {
|
|
|
7682
8489
|
title: stringValue$1(data.title),
|
|
7683
8490
|
textContent: stringValue$1(data.text_content),
|
|
7684
8491
|
sendAtMillis: epochMillisValue(data.send_at),
|
|
7685
|
-
templateKind: integerLikeValue
|
|
7686
|
-
displayKind: integerLikeValue
|
|
7687
|
-
officialMark: integerLikeValue
|
|
8492
|
+
templateKind: integerLikeValue(data.template_kind),
|
|
8493
|
+
displayKind: integerLikeValue(data.display_kind),
|
|
8494
|
+
officialMark: integerLikeValue(data.official_mark),
|
|
7688
8495
|
mediaItems: listValue$16(data.media_items).map(messageCopyLinkMediaItemFromData),
|
|
7689
8496
|
...structuredContent === void 0 ? {} : { structuredContent }
|
|
7690
8497
|
};
|
|
@@ -7700,7 +8507,7 @@ function messageCopyLinkPresentationNodesFromData(value, itemCount, depth = 1, s
|
|
|
7700
8507
|
const data = objectValue$1(rawNode);
|
|
7701
8508
|
const kind = stringValue$1(data.kind);
|
|
7702
8509
|
if (kind === "item") {
|
|
7703
|
-
const itemIndex = integerLikeValue
|
|
8510
|
+
const itemIndex = integerLikeValue(data.item_index);
|
|
7704
8511
|
if (itemIndex < 0 || itemIndex >= itemCount || seenItemIndexes.has(itemIndex)) throw new ArkmePluginError("message-copy-link-unavailable", "链接暂不可用", false, 404);
|
|
7705
8512
|
seenItemIndexes.add(itemIndex);
|
|
7706
8513
|
return {
|
|
@@ -7712,7 +8519,7 @@ function messageCopyLinkPresentationNodesFromData(value, itemCount, depth = 1, s
|
|
|
7712
8519
|
kind: "forward_bundle",
|
|
7713
8520
|
title: stringValue$1(data.title),
|
|
7714
8521
|
commentText: stringValue$1(data.comment_text),
|
|
7715
|
-
createdAtMillis: integerLikeValue
|
|
8522
|
+
createdAtMillis: integerLikeValue(data.created_at),
|
|
7716
8523
|
senderDisplayName: stringValue$1(data.sender_display_name),
|
|
7717
8524
|
children: messageCopyLinkPresentationNodesFromData(data.children, itemCount, depth + 1, seenItemIndexes)
|
|
7718
8525
|
};
|
|
@@ -7724,8 +8531,8 @@ function messageCopyLinkSourceAnchorFromData(value) {
|
|
|
7724
8531
|
return {
|
|
7725
8532
|
relationUid: stringValue$1(data.rel_uid),
|
|
7726
8533
|
recordUid: stringValue$1(data.record_uid),
|
|
7727
|
-
recordOwnerUserId: integerLikeValue
|
|
7728
|
-
sequence: integerLikeValue
|
|
8534
|
+
recordOwnerUserId: integerLikeValue(data.record_owner_user_id),
|
|
8535
|
+
sequence: integerLikeValue(data.seq)
|
|
7729
8536
|
};
|
|
7730
8537
|
}
|
|
7731
8538
|
function firstTextValue(source, keys) {
|
|
@@ -7772,7 +8579,7 @@ function messageCopyLinkExtensionItemFromData(value) {
|
|
|
7772
8579
|
if (recordUid === "" || sendAtMillis <= 0 || title.trim() === "" && textContent.trim() === "" && mediaItems.length === 0 && structuredContent === void 0) return;
|
|
7773
8580
|
return {
|
|
7774
8581
|
recordUid,
|
|
7775
|
-
level: Math.max(2, integerLikeValue
|
|
8582
|
+
level: Math.max(2, integerLikeValue(data.level) || 2),
|
|
7776
8583
|
sourceKind: stringValue$1(data.source_kind ?? data.sourceKind) || "record_extension",
|
|
7777
8584
|
senderDisplayName,
|
|
7778
8585
|
senderAvatarUrl: firstTextValue(data, [
|
|
@@ -7787,9 +8594,9 @@ function messageCopyLinkExtensionItemFromData(value) {
|
|
|
7787
8594
|
title,
|
|
7788
8595
|
textContent,
|
|
7789
8596
|
sendAtMillis,
|
|
7790
|
-
templateKind: integerLikeValue
|
|
7791
|
-
displayKind: integerLikeValue
|
|
7792
|
-
officialMark: integerLikeValue
|
|
8597
|
+
templateKind: integerLikeValue(data.template_kind ?? data.templateKind ?? core.template_kind ?? core.templateKind) || 1,
|
|
8598
|
+
displayKind: integerLikeValue(data.display_kind ?? data.displayKind ?? core.display_kind ?? core.displayKind),
|
|
8599
|
+
officialMark: integerLikeValue(data.official_mark ?? data.officialMark ?? core.official_mark ?? core.officialMark),
|
|
7793
8600
|
mediaItems,
|
|
7794
8601
|
...structuredContent === void 0 ? {} : { structuredContent }
|
|
7795
8602
|
};
|
|
@@ -7797,7 +8604,7 @@ function messageCopyLinkExtensionItemFromData(value) {
|
|
|
7797
8604
|
function messageCopyLinkRecordContextFromData(data) {
|
|
7798
8605
|
const context = objectValue$1(data.record_context ?? data.recordContext);
|
|
7799
8606
|
const extensions = listValue$16(context.extensions ?? context.extend_records ?? context.extendRecords ?? context.list ?? data.extensions ?? data.extend_records ?? data.extendRecords ?? data.list).map(messageCopyLinkExtensionItemFromData).filter((item) => item !== void 0);
|
|
7800
|
-
const extensionCount = Math.max(integerLikeValue
|
|
8607
|
+
const extensionCount = Math.max(integerLikeValue(context.extension_count ?? context.extensionCount ?? context.total ?? data.extension_count ?? data.extensionCount ?? data.total), extensions.length);
|
|
7801
8608
|
if (extensionCount <= 0 && extensions.length === 0) return void 0;
|
|
7802
8609
|
extensions.sort((left, right) => right.sendAtMillis - left.sendAtMillis);
|
|
7803
8610
|
return {
|
|
@@ -7845,7 +8652,7 @@ function parsedObject(value) {
|
|
|
7845
8652
|
}
|
|
7846
8653
|
function firstInteger(source, keys) {
|
|
7847
8654
|
for (const key of keys) {
|
|
7848
|
-
const value = integerLikeValue
|
|
8655
|
+
const value = integerLikeValue(source[key]);
|
|
7849
8656
|
if (value > 0) return value;
|
|
7850
8657
|
}
|
|
7851
8658
|
return 0;
|
|
@@ -7882,8 +8689,20 @@ function resolveChatMemberDisplayNames(input) {
|
|
|
7882
8689
|
].find((value) => isUsable(value) && value !== displayName) ?? ""
|
|
7883
8690
|
};
|
|
7884
8691
|
}
|
|
8692
|
+
function projectChatMemberDisplayNames(item, userId, viewerLabel, publicDisplayName) {
|
|
8693
|
+
return resolveChatMemberDisplayNames({
|
|
8694
|
+
userId,
|
|
8695
|
+
remarkCandidates: [],
|
|
8696
|
+
memberNameCandidates: [item.display_name_snapshot],
|
|
8697
|
+
userNameCandidates: [
|
|
8698
|
+
viewerLabel,
|
|
8699
|
+
item.remark,
|
|
8700
|
+
publicDisplayName
|
|
8701
|
+
]
|
|
8702
|
+
});
|
|
8703
|
+
}
|
|
7885
8704
|
function normalizedJoinTimestamp(value) {
|
|
7886
|
-
const raw = integerLikeValue
|
|
8705
|
+
const raw = integerLikeValue(value);
|
|
7887
8706
|
if (raw <= 0) return 0;
|
|
7888
8707
|
return raw < 1e11 ? raw * 1e3 : raw;
|
|
7889
8708
|
}
|
|
@@ -7900,12 +8719,12 @@ function rawMemberDisplayName(item) {
|
|
|
7900
8719
|
async function projectArkmeConversationMemberJoinEvents(rawItems, options) {
|
|
7901
8720
|
const membersByUserId = /* @__PURE__ */ new Map();
|
|
7902
8721
|
for (const item of rawItems) {
|
|
7903
|
-
const userId = integerLikeValue
|
|
8722
|
+
const userId = integerLikeValue(item.user_id ?? item.userId);
|
|
7904
8723
|
if (userId > 0) membersByUserId.set(userId, item);
|
|
7905
8724
|
}
|
|
7906
8725
|
const groups = /* @__PURE__ */ new Map();
|
|
7907
8726
|
for (const item of rawItems) {
|
|
7908
|
-
const inviteeUserId = integerLikeValue
|
|
8727
|
+
const inviteeUserId = integerLikeValue(item.user_id ?? item.userId);
|
|
7909
8728
|
if (inviteeUserId <= 0) continue;
|
|
7910
8729
|
const extra = parsedObject(item.extra);
|
|
7911
8730
|
if (Object.keys(extra).length === 0) continue;
|
|
@@ -8011,7 +8830,7 @@ function agentSourceLabel(displayName) {
|
|
|
8011
8830
|
function isAgentCreationSource(relation, record, payload) {
|
|
8012
8831
|
const relationMetadata = objectValue$1(relation.metadata);
|
|
8013
8832
|
const recordMetadata = objectValue$1(record.metadata);
|
|
8014
|
-
return integerLikeValue
|
|
8833
|
+
return integerLikeValue(payload.creation_source ?? payload.creationSource) === 1 || integerLikeValue(record.creation_source ?? record.creationSource) === 1 || integerLikeValue(relation.creation_source ?? relation.creationSource) === 1 || integerLikeValue(recordMetadata.creation_source ?? recordMetadata.creationSource) === 1 || integerLikeValue(relationMetadata.creation_source ?? relationMetadata.creationSource) === 1;
|
|
8015
8834
|
}
|
|
8016
8835
|
function agentDisplayNameFromTimeline(relation, record, payload) {
|
|
8017
8836
|
const relationMetadata = objectValue$1(relation.metadata);
|
|
@@ -8251,7 +9070,11 @@ var ChatService = class {
|
|
|
8251
9070
|
const joinEventsEnabled = source.kind === "group_chat" && this.runtime.config.chatMemberJoinEventsEnabled !== false;
|
|
8252
9071
|
const rawItems = await this.rawChatMembers(source.ownerRef, joinEventsEnabled ? false : activeOnly, session, options.signal);
|
|
8253
9072
|
const visibleRawItems = activeOnly ? rawItems.filter((item) => chatMemberStatus$1(item.status) === "active") : rawItems;
|
|
8254
|
-
const members = await this.projectChatMembers(source.ownerRef, visibleRawItems, session,
|
|
9073
|
+
const members = await this.projectChatMembers(source.ownerRef, visibleRawItems, session, {
|
|
9074
|
+
includeViewerLabels: source.kind === "group_chat",
|
|
9075
|
+
includeHumanMentionRefs: source.kind === "group_chat",
|
|
9076
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
9077
|
+
});
|
|
8255
9078
|
const signingKey = joinEventsEnabled ? await this.runtime.stateStore.uniqueCode() : "";
|
|
8256
9079
|
const joinEvents = joinEventsEnabled ? await projectArkmeConversationMemberJoinEvents(rawItems, {
|
|
8257
9080
|
viewerUserId: session.userId,
|
|
@@ -8273,7 +9096,11 @@ var ChatService = class {
|
|
|
8273
9096
|
if (mode !== "owner" && mode !== "mentioned") throw new ArkmePluginError("chat-member-record-mode-invalid", "成员快记模式无效", false);
|
|
8274
9097
|
const reference = await this.openChatMemberRef(memberRef, session.userId, source.ownerRef);
|
|
8275
9098
|
const rawMembers = await this.rawChatMembers(source.ownerRef, false, session, options.signal);
|
|
8276
|
-
const member = (await this.projectChatMembers(source.ownerRef, rawMembers, session,
|
|
9099
|
+
const member = (await this.projectChatMembers(source.ownerRef, rawMembers, session, {
|
|
9100
|
+
includeViewerLabels: source.kind === "group_chat",
|
|
9101
|
+
includeHumanMentionRefs: source.kind === "group_chat",
|
|
9102
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
9103
|
+
})).find((item) => item.memberRef === memberRef);
|
|
8277
9104
|
if (member === void 0) throw new ArkmePluginError("chat-member-ref-stale", "该成员已不属于当前会话,请刷新后重试", false, 409);
|
|
8278
9105
|
const limit = Math.min(50, Math.max(1, Math.trunc(options.limit ?? 30)));
|
|
8279
9106
|
const data = await this.runtime.authenticatedChatPost("/api/v1/chats/members/records/page", {
|
|
@@ -8422,6 +9249,7 @@ var ChatService = class {
|
|
|
8422
9249
|
}, session, options.signal);
|
|
8423
9250
|
const rawRecords = listValue$16(data.items).filter((raw) => !arkmePrivacyLockedRecord(raw) && !lockedRecordUids.has(this.record.recordUid(raw)));
|
|
8424
9251
|
const media = await this.media.hydrateRecordMediaPage(rawRecords, session, options.signal);
|
|
9252
|
+
const signingKey = await this.runtime.stateStore.uniqueCode();
|
|
8425
9253
|
const items = (await Promise.all(rawRecords.map(async (raw) => {
|
|
8426
9254
|
const recordUid = this.record.recordUid(raw);
|
|
8427
9255
|
const displayItems = media.displayItemsByRecordUid.get(recordUid);
|
|
@@ -8438,7 +9266,7 @@ var ChatService = class {
|
|
|
8438
9266
|
} },
|
|
8439
9267
|
mediaUnavailable: media.unavailableRecordUids.has(recordUid)
|
|
8440
9268
|
});
|
|
8441
|
-
}))).filter((item) => item.itemUid !== "");
|
|
9269
|
+
}))).filter((item) => item.itemUid !== "").map((item) => this.withRecordMessageActionRef(source, item, session.userId, signingKey));
|
|
8442
9270
|
const nextSendAt = numberValue$16(data.next_cursor_send_at);
|
|
8443
9271
|
const nextUid = stringValue$1(data.next_cursor_record_uid).trim();
|
|
8444
9272
|
return {
|
|
@@ -8478,6 +9306,7 @@ var ChatService = class {
|
|
|
8478
9306
|
if (arkmePrivacyLockedTopic(data.topic_core)) throw new ArkmePluginError("topic-privacy-locked", "隐私锁主题不能在 Arkme 插件中查看", false, 403);
|
|
8479
9307
|
const rawRecords = listValue$16(data.records).filter((raw) => !arkmePrivacyLockedRecord(raw) && !lockedRecordUids.has(this.record.recordUid(raw)));
|
|
8480
9308
|
const media = await this.media.hydrateRecordMediaPage(rawRecords, session, options.signal);
|
|
9309
|
+
const signingKey = await this.runtime.stateStore.uniqueCode();
|
|
8481
9310
|
const records = rawRecords.map((raw) => {
|
|
8482
9311
|
const recordUid = this.record.recordUid(raw);
|
|
8483
9312
|
const displayItems = media.displayItemsByRecordUid.get(recordUid);
|
|
@@ -8490,7 +9319,7 @@ var ChatService = class {
|
|
|
8490
9319
|
const nextUid = stringValue$1(data.next_cursor_record_uid).trim();
|
|
8491
9320
|
return {
|
|
8492
9321
|
source: await this.source.sourceItem(source),
|
|
8493
|
-
items: records,
|
|
9322
|
+
items: records.map((item) => this.withRecordMessageActionRef(source, item, session.userId, signingKey)),
|
|
8494
9323
|
hasMore: data.has_more === true,
|
|
8495
9324
|
...nextSendAt > 0 && nextUid !== "" ? { nextCursor: {
|
|
8496
9325
|
sendAtMillis: nextSendAt,
|
|
@@ -8770,7 +9599,7 @@ var ChatService = class {
|
|
|
8770
9599
|
bypassCache: true
|
|
8771
9600
|
});
|
|
8772
9601
|
const rawItems = listValue$16(data.list ?? data.items);
|
|
8773
|
-
if (offset === 0) total = Math.max(0, integerLikeValue
|
|
9602
|
+
if (offset === 0) total = Math.max(0, integerLikeValue(data.total));
|
|
8774
9603
|
const pageItems = rawItems.map((raw) => messageCopyLinkExtensionItemFromData(raw)).filter((item) => item !== void 0);
|
|
8775
9604
|
extensions.push(...pageItems);
|
|
8776
9605
|
if (rawItems.length === 0) break;
|
|
@@ -8829,12 +9658,7 @@ var ChatService = class {
|
|
|
8829
9658
|
const publishedRecordUid = stringValue$1(data.record_uid).trim() || createdRecordUid;
|
|
8830
9659
|
const senderDisplayName = profile.nickname.trim() || profile.displayName.trim() || "我";
|
|
8831
9660
|
const senderAvatarUrl = profile.avatarRef.trim();
|
|
8832
|
-
this.
|
|
8833
|
-
this.realtime.emitChatClientEvent({
|
|
8834
|
-
type: "projection-invalidated",
|
|
8835
|
-
revision: this.realtime.nextChatClientRevision(),
|
|
8836
|
-
projection: "record"
|
|
8837
|
-
});
|
|
9661
|
+
await this.realtime.invalidateRecordProjection();
|
|
8838
9662
|
return {
|
|
8839
9663
|
sid: detail.sid,
|
|
8840
9664
|
recordUid: publishedRecordUid,
|
|
@@ -8929,7 +9753,7 @@ var ChatService = class {
|
|
|
8929
9753
|
content_payload: contentPayload,
|
|
8930
9754
|
send_at: Date.now()
|
|
8931
9755
|
}, session, options.signal);
|
|
8932
|
-
this.
|
|
9756
|
+
await this.realtime.invalidateRecordProjection();
|
|
8933
9757
|
return await appendCommentWarning({
|
|
8934
9758
|
sourceRef: targetSourceRef,
|
|
8935
9759
|
itemUid: stringValue$1(data.record_uid).trim() || recordUid,
|
|
@@ -8945,7 +9769,7 @@ var ChatService = class {
|
|
|
8945
9769
|
content_payload: contentPayload,
|
|
8946
9770
|
send_at: Date.now()
|
|
8947
9771
|
}, session, options.signal);
|
|
8948
|
-
this.
|
|
9772
|
+
await this.realtime.invalidateRecordProjection();
|
|
8949
9773
|
return await appendCommentWarning({
|
|
8950
9774
|
sourceRef: targetSourceRef,
|
|
8951
9775
|
itemUid: stringValue$1(data.record_uid).trim() || recordUid,
|
|
@@ -8960,8 +9784,11 @@ var ChatService = class {
|
|
|
8960
9784
|
if (text === "" || text.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("source-text-invalid", "发送内容为空或超过长度限制", false);
|
|
8961
9785
|
const recordUid = options.recordUid?.trim() || randomUUID();
|
|
8962
9786
|
if (source.kind === "send_to_self" || source.kind === "default_category") {
|
|
8963
|
-
const result = await this.record.createTextForConversation(recordUid, text
|
|
8964
|
-
|
|
9787
|
+
const result = await this.record.createTextForConversation(recordUid, text, {
|
|
9788
|
+
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
9789
|
+
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext }
|
|
9790
|
+
});
|
|
9791
|
+
if (result.localState !== "failed") await this.realtime.invalidateRecordProjection();
|
|
8965
9792
|
return {
|
|
8966
9793
|
sourceRef,
|
|
8967
9794
|
itemUid: result.recordUid,
|
|
@@ -8971,15 +9798,18 @@ var ChatService = class {
|
|
|
8971
9798
|
};
|
|
8972
9799
|
}
|
|
8973
9800
|
if (source.kind === "topic") {
|
|
9801
|
+
const captureContext = options.captureContext === void 0 ? void 0 : arkmeRecordCaptureContextPayload(options.captureContext);
|
|
8974
9802
|
const result = await this.runtime.authenticatedPost("/api/v1/topics/records/create", {
|
|
8975
9803
|
topic_uid: source.ownerRef,
|
|
8976
9804
|
record_uid: recordUid,
|
|
8977
9805
|
template_kind: 1,
|
|
8978
9806
|
title: "",
|
|
8979
9807
|
text_content: text,
|
|
9808
|
+
...Math.max(0, Math.trunc(options.recordDurationMillis ?? 0)) === 0 ? {} : { record_duration_millis: Math.max(0, Math.trunc(options.recordDurationMillis ?? 0)) },
|
|
9809
|
+
...captureContext === void 0 || Object.keys(captureContext).length === 0 ? {} : { capture_context: captureContext },
|
|
8980
9810
|
send_at: Date.now()
|
|
8981
9811
|
}, session);
|
|
8982
|
-
this.
|
|
9812
|
+
await this.realtime.invalidateRecordProjection();
|
|
8983
9813
|
return {
|
|
8984
9814
|
sourceRef,
|
|
8985
9815
|
itemUid: stringValue$1(result.record_uid).trim() || recordUid,
|
|
@@ -8992,61 +9822,45 @@ var ChatService = class {
|
|
|
8992
9822
|
let sent;
|
|
8993
9823
|
if (source.kind === "group_chat") {
|
|
8994
9824
|
if ((options.botRefs?.length ?? 0) > 0 && ((options.humanMentions?.length ?? 0) > 0 || (options.botMentions?.length ?? 0) > 0)) throw new ArkmePluginError("mention-kind-conflict", "bot_refs 不能和结构化 mention 同时使用", false);
|
|
8995
|
-
if (options.botRefs !== void 0 && options.botRefs.length > 0) sent = await this.groupBotMentionSend(sourceRef, source, text, options.botRefs, recordUid, relationUid, session, options.signal, {
|
|
9825
|
+
if (options.botRefs !== void 0 && options.botRefs.length > 0) sent = await this.groupBotMentionSend(sourceRef, source, text, options.botRefs, recordUid, relationUid, session, options.signal, {
|
|
9826
|
+
agentAuthored,
|
|
9827
|
+
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
9828
|
+
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext }
|
|
9829
|
+
});
|
|
8996
9830
|
else if ((options.humanMentions?.length ?? 0) > 0 || (options.botMentions?.length ?? 0) > 0) {
|
|
8997
|
-
const contentPayload = await this.
|
|
8998
|
-
sent = await this.sendChatSourceTextRaw(sourceRef, source.ownerRef, text, recordUid, relationUid, session, void 0, contentPayload, options.signal, {
|
|
9831
|
+
const contentPayload = await this.mentionContentPayload(source, textContent, text, options.humanMentions ?? [], options.botMentions ?? [], session, options.signal);
|
|
9832
|
+
sent = await this.sendChatSourceTextRaw(sourceRef, source.ownerRef, text, recordUid, relationUid, session, void 0, contentPayload, options.signal, {
|
|
9833
|
+
agentAuthored,
|
|
9834
|
+
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
9835
|
+
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext }
|
|
9836
|
+
});
|
|
8999
9837
|
} else sent = await this.aiPolish.sendGroupSourceTextWithAiPolish(sourceRef, source.ownerRef, text, recordUid, relationUid, session, {
|
|
9000
9838
|
agentAuthored,
|
|
9839
|
+
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
9840
|
+
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext },
|
|
9001
9841
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
9002
9842
|
});
|
|
9003
9843
|
} else if ((options.humanMentions?.length ?? 0) > 0) throw new ArkmePluginError("mention-group-required", "真人 mention 只能发送到群聊", false);
|
|
9004
9844
|
else if ((options.botRefs?.length ?? 0) > 0) throw new ArkmePluginError("mention-group-required", "bot_refs 只能发送到群聊", false);
|
|
9005
9845
|
else if ((options.botMentions?.length ?? 0) > 0) {
|
|
9006
|
-
const contentPayload = await this.
|
|
9007
|
-
sent = await this.sendChatSourceTextRaw(sourceRef, source.ownerRef, text, recordUid, relationUid, session, void 0, contentPayload, options.signal, {
|
|
9008
|
-
|
|
9846
|
+
const contentPayload = await this.mentionContentPayload(source, textContent, text, [], options.botMentions ?? [], session, options.signal);
|
|
9847
|
+
sent = await this.sendChatSourceTextRaw(sourceRef, source.ownerRef, text, recordUid, relationUid, session, void 0, contentPayload, options.signal, {
|
|
9848
|
+
agentAuthored,
|
|
9849
|
+
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
9850
|
+
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext }
|
|
9851
|
+
});
|
|
9852
|
+
} else sent = await this.sendChatSourceTextRaw(sourceRef, source.ownerRef, text, recordUid, relationUid, session, void 0, void 0, options.signal, {
|
|
9853
|
+
agentAuthored,
|
|
9854
|
+
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
9855
|
+
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext }
|
|
9856
|
+
});
|
|
9009
9857
|
if (agentAuthored && sent.localState === "synced") this.arko.agentSourceDisplayName(session);
|
|
9010
9858
|
return sent;
|
|
9011
9859
|
}
|
|
9012
|
-
async
|
|
9013
|
-
if (
|
|
9860
|
+
async mentionContentPayload(source, rawText, normalizedText, humanInputs, botInputs, session, signal) {
|
|
9861
|
+
if (humanInputs.length > 50) throw new ArkmePluginError("human-mention-invalid", "单条消息 mention 数量过多", false);
|
|
9014
9862
|
if (botInputs.length > 50) throw new ArkmePluginError("bot-mention-invalid", "单条消息 Bot mention 数量过多", false);
|
|
9015
|
-
const
|
|
9016
|
-
const rawMembers = inputs.length === 0 ? [] : await this.rawChatMembers(source.ownerRef, true, session, signal);
|
|
9017
|
-
const membersByUserId = new Map(rawMembers.map((item) => [Math.trunc(numberValue$16(item.user_id)), item]));
|
|
9018
|
-
const mentions = [];
|
|
9019
|
-
for (const input of [...inputs].sort((left, right) => left.startIndex - right.startIndex)) {
|
|
9020
|
-
const memberRef = input.memberRef?.trim() ?? "";
|
|
9021
|
-
const startIndex = Math.trunc(input.startIndex) - leadingTrim;
|
|
9022
|
-
const length = Math.trunc(input.length);
|
|
9023
|
-
if (startIndex < 0 || length < 2 || startIndex + length > normalizedText.length) throw new ArkmePluginError("human-mention-invalid", "真人 mention 引用或文本区间无效", false);
|
|
9024
|
-
const visible = normalizedText.slice(startIndex, startIndex + length);
|
|
9025
|
-
const displayName = visible.startsWith("@") ? visible.slice(1).trim() : "";
|
|
9026
|
-
let userId;
|
|
9027
|
-
if (input.all === true) {
|
|
9028
|
-
if (displayName !== "所有人") throw new ArkmePluginError("human-mention-text-mismatch", "真人 mention 文本已变化,请重新选择成员", false, 409);
|
|
9029
|
-
userId = 0;
|
|
9030
|
-
} else {
|
|
9031
|
-
if (memberRef === "") throw new ArkmePluginError("human-mention-invalid", "真人 mention 引用或文本区间无效", false);
|
|
9032
|
-
const reference = await this.openChatMemberRef(memberRef, session.userId, source.ownerRef);
|
|
9033
|
-
if (reference.targetUserId === session.userId) throw new ArkmePluginError("human-mention-self-invalid", "不能 @ 自己", false);
|
|
9034
|
-
const rawMember = membersByUserId.get(reference.targetUserId);
|
|
9035
|
-
if (rawMember === void 0) throw new ArkmePluginError("chat-member-ref-stale", "被 @ 成员已不在当前群聊", false, 409);
|
|
9036
|
-
const expectedNames = [stringValue$1(rawMember.remark).trim(), stringValue$1(rawMember.display_name_snapshot).trim()].filter((value) => value !== "");
|
|
9037
|
-
if (displayName === "" || !expectedNames.includes(displayName)) throw new ArkmePluginError("human-mention-text-mismatch", "真人 mention 文本已变化,请重新选择成员", false, 409);
|
|
9038
|
-
userId = reference.targetUserId;
|
|
9039
|
-
}
|
|
9040
|
-
const previous = mentions.at(-1);
|
|
9041
|
-
if (previous !== void 0 && previous.start_index + previous.length > startIndex) throw new ArkmePluginError("human-mention-overlap", "真人 mention 文本区间重叠", false);
|
|
9042
|
-
mentions.push({
|
|
9043
|
-
user_id: userId,
|
|
9044
|
-
display_name_snapshot: displayName,
|
|
9045
|
-
start_index: startIndex,
|
|
9046
|
-
length
|
|
9047
|
-
});
|
|
9048
|
-
}
|
|
9049
|
-
const botMentions = await this.botMentionMetadata(source, rawText, normalizedText, botInputs, session, signal);
|
|
9863
|
+
const [mentions, botMentions] = await Promise.all([this.humanMentionMetadata(source, rawText, normalizedText, humanInputs, session, signal), this.botMentionMetadata(source, rawText, normalizedText, botInputs, session, signal)]);
|
|
9050
9864
|
const orderedRanges = [...mentions.map((mention) => ({
|
|
9051
9865
|
startIndex: mention.start_index,
|
|
9052
9866
|
length: mention.length
|
|
@@ -9084,6 +9898,45 @@ var ChatService = class {
|
|
|
9084
9898
|
}
|
|
9085
9899
|
};
|
|
9086
9900
|
}
|
|
9901
|
+
async humanMentionMetadata(source, rawText, normalizedText, inputs, session, signal) {
|
|
9902
|
+
const leadingTrim = rawText.length - rawText.trimStart().length;
|
|
9903
|
+
const rawMembers = inputs.some((input) => input.all !== true) ? await this.rawChatMembers(source.ownerRef, true, session, signal) : [];
|
|
9904
|
+
const membersByUserId = new Map(rawMembers.map((item) => [Math.trunc(numberValue$16(item.user_id)), item]));
|
|
9905
|
+
const mentions = [];
|
|
9906
|
+
for (const input of [...inputs].sort((left, right) => left.startIndex - right.startIndex)) {
|
|
9907
|
+
const rawInput = input;
|
|
9908
|
+
const mentionRef = input.mentionRef?.trim() ?? "";
|
|
9909
|
+
const memberRef = stringValue$1(rawInput.memberRef).trim();
|
|
9910
|
+
const startIndex = Math.trunc(input.startIndex) - leadingTrim;
|
|
9911
|
+
const length = Math.trunc(input.length);
|
|
9912
|
+
if (startIndex < 0 || length < 2 || startIndex + length > normalizedText.length) throw new ArkmePluginError("human-mention-invalid", "真人 mention 引用或文本区间无效", false);
|
|
9913
|
+
const visible = normalizedText.slice(startIndex, startIndex + length);
|
|
9914
|
+
const displayName = visible.startsWith("@") ? visible.slice(1) : "";
|
|
9915
|
+
let userId;
|
|
9916
|
+
if (input.all === true) {
|
|
9917
|
+
if (mentionRef !== "" || memberRef !== "") throw new ArkmePluginError("human-mention-invalid", "@所有人不能携带成员引用", false);
|
|
9918
|
+
if (displayName !== "所有人") throw new ArkmePluginError("human-mention-text-mismatch", "真人 mention 文本已变化,请重新选择成员", false, 409);
|
|
9919
|
+
userId = 0;
|
|
9920
|
+
} else {
|
|
9921
|
+
if (mentionRef === "" || memberRef !== "") throw new ArkmePluginError("human-mention-invalid", "真人 mention 必须且只能携带 mention 引用", false);
|
|
9922
|
+
const reference = await this.openChatHumanMentionRef(mentionRef, session.userId, source.ownerRef);
|
|
9923
|
+
const targetUserId = reference.targetUserId;
|
|
9924
|
+
if (targetUserId === session.userId) throw new ArkmePluginError("human-mention-self-invalid", "不能 @ 自己", false);
|
|
9925
|
+
if (membersByUserId.get(targetUserId) === void 0) throw new ArkmePluginError("chat-member-ref-stale", "被 @ 成员已不在当前群聊", false, 409);
|
|
9926
|
+
if (displayName === "" || displayName !== reference.displayNameSnapshot) throw new ArkmePluginError("human-mention-text-mismatch", "真人 mention 文本已变化,请重新选择成员", false, 409);
|
|
9927
|
+
userId = targetUserId;
|
|
9928
|
+
}
|
|
9929
|
+
const previous = mentions.at(-1);
|
|
9930
|
+
if (previous !== void 0 && previous.start_index + previous.length > startIndex) throw new ArkmePluginError("human-mention-overlap", "真人 mention 文本区间重叠", false);
|
|
9931
|
+
mentions.push({
|
|
9932
|
+
user_id: userId,
|
|
9933
|
+
display_name_snapshot: displayName,
|
|
9934
|
+
start_index: startIndex,
|
|
9935
|
+
length
|
|
9936
|
+
});
|
|
9937
|
+
}
|
|
9938
|
+
return mentions;
|
|
9939
|
+
}
|
|
9087
9940
|
async botMentionMetadata(source, rawText, normalizedText, inputs, session, signal) {
|
|
9088
9941
|
if (inputs.length === 0) return [];
|
|
9089
9942
|
if (source.kind !== "group_chat" && source.kind !== "private_chat") throw new ArkmePluginError("mention-chat-required", "Bot mention 只能发送到聊天", false);
|
|
@@ -9207,6 +10060,8 @@ var ChatService = class {
|
|
|
9207
10060
|
rel_uid: relationUid,
|
|
9208
10061
|
template_kind: 1,
|
|
9209
10062
|
text_content: text,
|
|
10063
|
+
...Math.max(0, Math.trunc(options.recordDurationMillis ?? 0)) === 0 ? {} : { record_duration_millis: Math.max(0, Math.trunc(options.recordDurationMillis ?? 0)) },
|
|
10064
|
+
...options.captureContext === void 0 ? {} : { capture_context: arkmeRecordCaptureContextPayload(options.captureContext) },
|
|
9210
10065
|
...options.agentAuthored === true ? { creation_source: 1 } : {},
|
|
9211
10066
|
...options.initialAiPolish === void 0 ? {} : { initial_ai_polish: options.initialAiPolish },
|
|
9212
10067
|
...options.contentPayload === void 0 ? {} : { content_payload: options.contentPayload },
|
|
@@ -9226,6 +10081,8 @@ var ChatService = class {
|
|
|
9226
10081
|
const longArticle = displayKind === 1;
|
|
9227
10082
|
const maxContentLength = longArticle ? 4e4 : this.runtime.config.maxTextLength;
|
|
9228
10083
|
const thinkingDurationMillis = Math.max(0, Math.trunc(input.thinkingDurationMillis ?? 0));
|
|
10084
|
+
const recordDurationMillis = Math.max(0, Math.trunc(input.recordDurationMillis ?? (longArticle ? thinkingDurationMillis : 0)));
|
|
10085
|
+
const captureContext = input.captureContext === void 0 ? void 0 : arkmeRecordCaptureContextPayload(input.captureContext);
|
|
9229
10086
|
if (title.length > (longArticle ? 100 : 500) || textContent.length > maxContentLength || assets.length > 20 || textContent === "" && title === "" && assets.length === 0) throw new ArkmePluginError("rich-content-invalid", "富内容为空、过长或附件数量超限", false);
|
|
9230
10087
|
if (longArticle && (title === "" || textContent === "")) throw new ArkmePluginError("long-article-invalid", "长文标题和正文不能为空", false);
|
|
9231
10088
|
for (const asset of assets) if (!/^[A-Za-z0-9._:-]{8,256}$/.test(asset.fileAssetUid) || asset.size < 0 || ![
|
|
@@ -9257,7 +10114,7 @@ var ChatService = class {
|
|
|
9257
10114
|
if ((input.humanMentions?.length ?? 0) > 0 && source.kind !== "group_chat") throw new ArkmePluginError("mention-group-required", "真人 mention 只能发送到群聊", false);
|
|
9258
10115
|
if ((input.botMentions?.length ?? 0) > 0 && source.kind !== "group_chat" && source.kind !== "private_chat") throw new ArkmePluginError("mention-chat-required", "Bot mention 只能发送到聊天", false);
|
|
9259
10116
|
if (longArticle) throw new ArkmePluginError("mention-rich-invalid", "长文暂不支持 mention", false);
|
|
9260
|
-
const mentionPayload = await this.
|
|
10117
|
+
const mentionPayload = await this.mentionContentPayload(source, input.textContent ?? "", textContent, input.humanMentions ?? [], input.botMentions ?? [], session, options.signal);
|
|
9261
10118
|
contentPayload = {
|
|
9262
10119
|
...mediaContentPayload ?? {},
|
|
9263
10120
|
...mentionPayload
|
|
@@ -9269,13 +10126,14 @@ var ChatService = class {
|
|
|
9269
10126
|
display_kind: displayKind,
|
|
9270
10127
|
title,
|
|
9271
10128
|
text_content: textContent,
|
|
9272
|
-
...
|
|
10129
|
+
...recordDurationMillis === 0 ? {} : { record_duration_millis: recordDurationMillis },
|
|
10130
|
+
...captureContext === void 0 || Object.keys(captureContext).length === 0 ? {} : { capture_context: captureContext },
|
|
9273
10131
|
...contentPayload === void 0 ? {} : { content_payload: contentPayload },
|
|
9274
10132
|
send_at: Date.now()
|
|
9275
10133
|
};
|
|
9276
10134
|
if (source.kind === "send_to_self" || source.kind === "default_category") {
|
|
9277
10135
|
const result = await this.runtime.authenticatedPost("/api/v1/records/create", commonBody, session, options.signal);
|
|
9278
|
-
this.
|
|
10136
|
+
await this.realtime.invalidateRecordProjection();
|
|
9279
10137
|
return {
|
|
9280
10138
|
sourceRef,
|
|
9281
10139
|
itemUid: stringValue$1(result.record_uid).trim() || recordUid,
|
|
@@ -9288,7 +10146,7 @@ var ChatService = class {
|
|
|
9288
10146
|
topic_uid: source.ownerRef,
|
|
9289
10147
|
...commonBody
|
|
9290
10148
|
}, session, options.signal);
|
|
9291
|
-
this.
|
|
10149
|
+
await this.realtime.invalidateRecordProjection();
|
|
9292
10150
|
return {
|
|
9293
10151
|
sourceRef,
|
|
9294
10152
|
itemUid: stringValue$1(result.record_uid).trim() || recordUid,
|
|
@@ -9539,8 +10397,9 @@ var ChatService = class {
|
|
|
9539
10397
|
const payload = objectValue$1(record.payload);
|
|
9540
10398
|
const uid = stringValue$1(relation.record_uid ?? payload.record_uid).trim();
|
|
9541
10399
|
if (uid === "") continue;
|
|
9542
|
-
const senderUserId =
|
|
10400
|
+
const senderUserId = integerLikeValue(relation.sender_user_id);
|
|
9543
10401
|
const relationUid = stringValue$1(relation.rel_uid ?? relation.relUid).trim();
|
|
10402
|
+
const recordOwnerUserId = chatRecordOwnerUserId(relation, record, payload, senderUserId);
|
|
9544
10403
|
const aiPolish = this.aiPolish.timelineAiPolish(record, payload);
|
|
9545
10404
|
const sendAtMillis = numberValue$16(relation.attach_at ?? payload.send_at);
|
|
9546
10405
|
const forwardRecords = await this.chatForwardRecordsPreview(item, session.userId, sendAtMillis);
|
|
@@ -9548,20 +10407,39 @@ var ChatService = class {
|
|
|
9548
10407
|
viewerUserId: session.userId,
|
|
9549
10408
|
chatSessionUid,
|
|
9550
10409
|
relationUid,
|
|
9551
|
-
recordOwnerUserId
|
|
10410
|
+
recordOwnerUserId,
|
|
9552
10411
|
recordUid: uid,
|
|
9553
|
-
senderUserId: integerLikeValue
|
|
9554
|
-
sequence: integerLikeValue
|
|
10412
|
+
senderUserId: integerLikeValue(relation.sender_user_id),
|
|
10413
|
+
sequence: integerLikeValue(relation.seq),
|
|
9555
10414
|
signingKey
|
|
9556
10415
|
});
|
|
9557
10416
|
const rawAgentSource = timelineAgentSource(relation, record, payload);
|
|
9558
10417
|
const agentSource = senderUserId === session.userId ? this.arko.currentUserAgentSourceFallback(session.userId, rawAgentSource) : rawAgentSource;
|
|
9559
10418
|
const contentBlocks = this.media.richContentBlocks(item, session.userId);
|
|
10419
|
+
const senderName = stringValue$1(relation.display_name_snapshot).trim() || "Arkme用户";
|
|
9560
10420
|
const mentionsViewer = senderUserId !== session.userId && arkmeMentionMetadataMentionsViewer(record, payload, session.userId);
|
|
9561
10421
|
items.push({
|
|
9562
10422
|
itemUid: uid,
|
|
10423
|
+
...relationUid === "" ? {} : { messageActionRef: this.sealMessageActionRef(this.messageActionRefPayload({
|
|
10424
|
+
sourceKind: "chat_relation",
|
|
10425
|
+
userId: session.userId,
|
|
10426
|
+
sourceOwnerRef: chatSessionUid,
|
|
10427
|
+
chatSessionUid,
|
|
10428
|
+
relationUid,
|
|
10429
|
+
recordOwnerUserId,
|
|
10430
|
+
recordUid: uid,
|
|
10431
|
+
senderUserId,
|
|
10432
|
+
senderName,
|
|
10433
|
+
title: stringValue$1(payload.title),
|
|
10434
|
+
textContent: stringValue$1(payload.text_content),
|
|
10435
|
+
sendAtMillis,
|
|
10436
|
+
sourceSequence: numberValue$16(relation.seq),
|
|
10437
|
+
templateKind: numberValue$16(payload.template_kind),
|
|
10438
|
+
displayKind: numberValue$16(payload.display_kind),
|
|
10439
|
+
contentBlocks
|
|
10440
|
+
}), signingKey) },
|
|
9563
10441
|
...senderUserId > 0 ? { memberRef: await this.sealChatMemberRef(session.userId, chatSessionUid, senderUserId) } : {},
|
|
9564
|
-
senderName
|
|
10442
|
+
senderName,
|
|
9565
10443
|
...agentSource === void 0 ? {} : { agentSource },
|
|
9566
10444
|
...senderUserId > 0 ? { avatarRef: await this.profile.sealProfileImageRef(session.userId, senderUserId) } : {},
|
|
9567
10445
|
isMe: senderUserId === session.userId,
|
|
@@ -9581,6 +10459,23 @@ var ChatService = class {
|
|
|
9581
10459
|
}
|
|
9582
10460
|
return items;
|
|
9583
10461
|
}
|
|
10462
|
+
async relatedQuickNoteLocator(sourceRef, messageActionRef) {
|
|
10463
|
+
const session = await this.runtime.requireSession();
|
|
10464
|
+
const normalizedSourceRef = sourceRef.trim();
|
|
10465
|
+
const source = await this.source.openSourceRef(normalizedSourceRef, session.userId);
|
|
10466
|
+
const reference = await this.openMessageActionRef(messageActionRef, session.userId, source);
|
|
10467
|
+
const ownerUserId = reference.recordOwnerUserId > 0 ? reference.recordOwnerUserId : reference.senderUserId;
|
|
10468
|
+
if (!Number.isSafeInteger(ownerUserId) || ownerUserId <= 0) throw new ArkmePluginError("related-quick-note-source-invalid", "当前快记缺少作者定位,请刷新后重试", false, 409);
|
|
10469
|
+
return {
|
|
10470
|
+
viewerUserId: session.userId,
|
|
10471
|
+
sourceRef: normalizedSourceRef,
|
|
10472
|
+
sourceOwnerRef: source.ownerRef,
|
|
10473
|
+
contextType: reference.sourceKind === "chat_relation" ? "chat" : "record",
|
|
10474
|
+
recordUid: reference.recordUid,
|
|
10475
|
+
recordOwnerUserId: ownerUserId,
|
|
10476
|
+
chatSessionUid: reference.sourceKind === "chat_relation" ? reference.chatSessionUid : ""
|
|
10477
|
+
};
|
|
10478
|
+
}
|
|
9584
10479
|
async chatForwardRecordsPreview(raw, viewerUserId, fallbackCreatedAtMillis) {
|
|
9585
10480
|
const contentPayload = this.media.recordContentPayload(raw);
|
|
9586
10481
|
const nested = objectValue$1(contentPayload.forward_records ?? contentPayload.forwardRecords);
|
|
@@ -9727,11 +10622,11 @@ var ChatService = class {
|
|
|
9727
10622
|
const participant = objectValue$1(value);
|
|
9728
10623
|
const displayName = stringValue$1(participant.display_name ?? participant.displayName ?? participant.nick_name ?? participant.nickName ?? participant.speaker_name ?? participant.speakerName ?? participant.name).trim();
|
|
9729
10624
|
if (displayName === "") return [];
|
|
9730
|
-
const refUserId = integerLikeValue
|
|
10625
|
+
const refUserId = integerLikeValue(participant.ref_user_id ?? participant.refUserId ?? participant.ref_usr_id ?? participant.refUsrId);
|
|
9731
10626
|
return [{
|
|
9732
10627
|
...refUserId > 0 ? { refUserId } : {},
|
|
9733
10628
|
displayName,
|
|
9734
|
-
role: Math.max(0, integerLikeValue
|
|
10629
|
+
role: Math.max(0, integerLikeValue(participant.role))
|
|
9735
10630
|
}];
|
|
9736
10631
|
});
|
|
9737
10632
|
}
|
|
@@ -9767,15 +10662,15 @@ var ChatService = class {
|
|
|
9767
10662
|
const sourceDigest = stringValue$1(payload.source_digest ?? payload.sourceDigest).trim();
|
|
9768
10663
|
const title = stringValue$1(payload.title ?? payload.orig_name ?? payload.origName).trim();
|
|
9769
10664
|
const summary = stringValue$1(payload.summary ?? payload.summary_text ?? payload.summaryText ?? payload.content_summary ?? payload.contentSummary).trim();
|
|
9770
|
-
const displayAtMillis = integerLikeValue
|
|
10665
|
+
const displayAtMillis = integerLikeValue(payload.display_at ?? payload.displayAt);
|
|
9771
10666
|
if (sourceDigest === "" || title === "" || summary === "" || displayAtMillis <= 0) return void 0;
|
|
9772
10667
|
const transcript = this.sharedRecordingTranscriptFromPayload(payload);
|
|
9773
10668
|
return {
|
|
9774
10669
|
sourceDigest,
|
|
9775
|
-
sharedByUserId: Math.max(0, integerLikeValue
|
|
9776
|
-
sharedAtMillis: Math.max(0, integerLikeValue
|
|
10670
|
+
sharedByUserId: Math.max(0, integerLikeValue(payload.shared_by_user_id ?? payload.sharedByUserId)),
|
|
10671
|
+
sharedAtMillis: Math.max(0, integerLikeValue(payload.shared_at ?? payload.sharedAt)),
|
|
9777
10672
|
displayAtMillis,
|
|
9778
|
-
endAtMillis: Math.max(0, integerLikeValue
|
|
10673
|
+
endAtMillis: Math.max(0, integerLikeValue(payload.end_at ?? payload.endAt)),
|
|
9779
10674
|
timeRangeText: stringValue$1(payload.time_range_text ?? payload.timeRangeText).trim(),
|
|
9780
10675
|
title,
|
|
9781
10676
|
summary,
|
|
@@ -9846,12 +10741,12 @@ var ChatService = class {
|
|
|
9846
10741
|
}
|
|
9847
10742
|
const result = {
|
|
9848
10743
|
version: 1,
|
|
9849
|
-
viewerUserId: integerLikeValue
|
|
10744
|
+
viewerUserId: integerLikeValue(parsed.viewerUserId),
|
|
9850
10745
|
chatSessionUid: stringValue$1(parsed.chatSessionUid).trim(),
|
|
9851
10746
|
relationUid: stringValue$1(parsed.relationUid).trim(),
|
|
9852
|
-
recordOwnerUserId: integerLikeValue
|
|
10747
|
+
recordOwnerUserId: integerLikeValue(parsed.recordOwnerUserId),
|
|
9853
10748
|
recordUid: stringValue$1(parsed.recordUid).trim(),
|
|
9854
|
-
sequence: Math.max(0, integerLikeValue
|
|
10749
|
+
sequence: Math.max(0, integerLikeValue(parsed.sequence))
|
|
9855
10750
|
};
|
|
9856
10751
|
if (parsed.version !== 1 || result.viewerUserId !== expectedViewerUserId || result.chatSessionUid === "" || result.recordUid === "" || result.recordOwnerUserId <= 0) throw new ArkmePluginError("shared-recording-detail-ref-invalid", "共享录音详情引用与当前账号不匹配,请刷新后重试", false, 403);
|
|
9857
10752
|
return result;
|
|
@@ -9877,35 +10772,177 @@ var ChatService = class {
|
|
|
9877
10772
|
detailRef
|
|
9878
10773
|
};
|
|
9879
10774
|
}
|
|
10775
|
+
async messageSnapshotDetail(sourceRef, actionRef, options = {}) {
|
|
10776
|
+
const session = await this.runtime.requireSession();
|
|
10777
|
+
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
10778
|
+
const isChatSource = source.kind === "private_chat" || source.kind === "group_chat";
|
|
10779
|
+
const isRecordSource = source.kind === "send_to_self" || source.kind === "default_category" || source.kind === "topic";
|
|
10780
|
+
if (!isChatSource && !isRecordSource) throw new ArkmePluginError("message-snapshot-source-unsupported", "当前对话暂不支持读取完整快记详情", false, 400);
|
|
10781
|
+
const reference = await this.openMessageActionRef(actionRef, session.userId, source);
|
|
10782
|
+
if (reference.recordUid === "") throw new ArkmePluginError("message-snapshot-record-invalid", "快记记录身份无效,请刷新后重试", false, 400);
|
|
10783
|
+
if (reference.senderUserId !== session.userId) throw new ArkmePluginError("message-snapshot-not-owned", "只能查看自己发送的快记详情", false, 403);
|
|
10784
|
+
const recordOwnerUserId = reference.recordOwnerUserId > 0 ? reference.recordOwnerUserId : reference.senderUserId;
|
|
10785
|
+
if (recordOwnerUserId <= 0) throw new ArkmePluginError("message-snapshot-owner-missing", "快记记录归属暂时无法确认,请刷新后重试", true, 502);
|
|
10786
|
+
if (reference.sourceKind === "record") {
|
|
10787
|
+
if (!isRecordSource) throw new ArkmePluginError("message-snapshot-record-invalid", "快记记录身份与当前来源不匹配,请刷新后重试", false, 400);
|
|
10788
|
+
return this.hydratedMessageSnapshotDetail(reference, session, options);
|
|
10789
|
+
}
|
|
10790
|
+
if (!isChatSource || reference.relationUid === "") throw new ArkmePluginError("message-snapshot-record-invalid", "快记记录身份无效,请刷新后重试", false, 400);
|
|
10791
|
+
const chatRaw = objectValue$1((await this.runtime.authenticatedChatPost("/api/v1/chats/records/detail", {
|
|
10792
|
+
chat_session_uid: reference.chatSessionUid,
|
|
10793
|
+
record_uid: reference.recordUid,
|
|
10794
|
+
record_owner_user_id: recordOwnerUserId,
|
|
10795
|
+
rel_uid: reference.relationUid,
|
|
10796
|
+
...reference.sourceSequence <= 0 ? {} : { seq: reference.sourceSequence }
|
|
10797
|
+
}, session, options.signal, {
|
|
10798
|
+
lane: "interactive-read",
|
|
10799
|
+
key: `message-snapshot-detail:${reference.chatSessionUid}:${reference.relationUid}:${reference.recordUid}:${String(reference.sourceSequence)}`,
|
|
10800
|
+
failureCooldownMs: 1e3
|
|
10801
|
+
})).item);
|
|
10802
|
+
if (Object.keys(chatRaw).length === 0) throw new ArkmePluginError("message-snapshot-detail-unavailable", "完整快记详情暂时无法读取,请稍后重试", true, 502);
|
|
10803
|
+
return this.hydratedMessageSnapshotDetail(reference, session, options, chatRaw);
|
|
10804
|
+
}
|
|
10805
|
+
async hydratedMessageSnapshotDetail(reference, session, options, chatRaw = {}) {
|
|
10806
|
+
const recordRaw = objectValue$1(await this.runtime.authenticatedPost("/api/v1/records/detail", { record_uid: reference.recordUid }, session, options.signal, {
|
|
10807
|
+
lane: "interactive-read",
|
|
10808
|
+
key: `message-snapshot-record-core:${reference.recordUid}`,
|
|
10809
|
+
failureCooldownMs: 1e3
|
|
10810
|
+
}));
|
|
10811
|
+
const chatRecord = objectValue$1(chatRaw.record);
|
|
10812
|
+
const recordCore = objectValue$1(recordRaw.record_core ?? recordRaw.recordCore ?? recordRaw.record ?? recordRaw);
|
|
10813
|
+
const detailRecordUid = firstSnapshotText(recordCore.record_uid, recordCore.recordUid, recordCore.uid, recordRaw.record_uid, recordRaw.recordUid, recordRaw.uid);
|
|
10814
|
+
const hasDetailPayload = [
|
|
10815
|
+
recordRaw.payload,
|
|
10816
|
+
recordRaw.content_payload,
|
|
10817
|
+
recordRaw.contentPayload,
|
|
10818
|
+
recordRaw.record_payload,
|
|
10819
|
+
recordRaw.recordPayload,
|
|
10820
|
+
recordRaw.location,
|
|
10821
|
+
recordRaw.position_detail,
|
|
10822
|
+
recordRaw.positionDetail,
|
|
10823
|
+
recordRaw.extra,
|
|
10824
|
+
recordRaw.record_extra,
|
|
10825
|
+
recordRaw.recordExtra,
|
|
10826
|
+
recordRaw.weather,
|
|
10827
|
+
recordRaw.capture_context,
|
|
10828
|
+
recordRaw.captureContext,
|
|
10829
|
+
recordRaw.background_sound,
|
|
10830
|
+
recordRaw.backgroundSound
|
|
10831
|
+
].some((value) => Object.keys(parsedObject(value)).length > 0 || listValue$16(value).length > 0);
|
|
10832
|
+
if (!Object.keys(recordCore).some((key) => ![
|
|
10833
|
+
"record_uid",
|
|
10834
|
+
"recordUid",
|
|
10835
|
+
"uid"
|
|
10836
|
+
].includes(key)) && !hasDetailPayload) throw new ArkmePluginError("message-snapshot-detail-unavailable", "完整快记详情暂时无法读取,请稍后重试", true, 502);
|
|
10837
|
+
if (detailRecordUid !== reference.recordUid) throw new ArkmePluginError("message-snapshot-detail-mismatch", "完整快记详情与当前消息不匹配,请刷新后重试", true, 502);
|
|
10838
|
+
const chatRecordPayload = {
|
|
10839
|
+
...parsedObject(chatRecord.payload),
|
|
10840
|
+
...parsedObject(chatRecord.content_payload),
|
|
10841
|
+
...parsedObject(chatRecord.contentPayload),
|
|
10842
|
+
...parsedObject(chatRecord.record_payload),
|
|
10843
|
+
...parsedObject(chatRecord.recordPayload)
|
|
10844
|
+
};
|
|
10845
|
+
const detailPayload = {
|
|
10846
|
+
...parsedObject(recordRaw.payload),
|
|
10847
|
+
...parsedObject(recordRaw.content_payload),
|
|
10848
|
+
...parsedObject(recordRaw.contentPayload),
|
|
10849
|
+
...parsedObject(recordRaw.record_payload),
|
|
10850
|
+
...parsedObject(recordRaw.recordPayload),
|
|
10851
|
+
...parsedObject(recordCore.payload),
|
|
10852
|
+
...parsedObject(recordCore.content_payload),
|
|
10853
|
+
...parsedObject(recordCore.contentPayload),
|
|
10854
|
+
...parsedObject(recordCore.record_payload),
|
|
10855
|
+
...parsedObject(recordCore.recordPayload)
|
|
10856
|
+
};
|
|
10857
|
+
let raw = {
|
|
10858
|
+
...chatRaw,
|
|
10859
|
+
...recordRaw,
|
|
10860
|
+
relation: Object.keys(chatRaw).length === 0 ? {
|
|
10861
|
+
record_uid: reference.recordUid,
|
|
10862
|
+
record_owner_user_id: reference.recordOwnerUserId
|
|
10863
|
+
} : objectValue$1(chatRaw.relation),
|
|
10864
|
+
record: {
|
|
10865
|
+
...chatRecord,
|
|
10866
|
+
...recordCore,
|
|
10867
|
+
payload: {
|
|
10868
|
+
...chatRecordPayload,
|
|
10869
|
+
...detailPayload
|
|
10870
|
+
}
|
|
10871
|
+
}
|
|
10872
|
+
};
|
|
10873
|
+
const locationContext = await this.runtime.authenticatedPost("/api/v1/records/location/context/get", { record_uid: reference.recordUid }, session, options.signal, {
|
|
10874
|
+
lane: "interactive-read",
|
|
10875
|
+
key: `message-snapshot-location-context:${reference.recordUid}`,
|
|
10876
|
+
failureCooldownMs: 1e4
|
|
10877
|
+
}).catch(() => void 0);
|
|
10878
|
+
if (locationContext !== void 0) {
|
|
10879
|
+
const context = snapshotLocationContext(locationContext);
|
|
10880
|
+
const contextEnvelope = objectValue$1(locationContext);
|
|
10881
|
+
const contextData = objectValue$1(contextEnvelope.data);
|
|
10882
|
+
const contextRecordUid = firstSnapshotText(contextEnvelope.record_uid, contextEnvelope.recordUid, contextEnvelope.uid, contextData.record_uid, contextData.recordUid, contextData.uid, context.record_uid, context.recordUid, context.uid);
|
|
10883
|
+
if (contextRecordUid !== void 0 && contextRecordUid !== reference.recordUid) throw new ArkmePluginError("message-snapshot-detail-mismatch", "快记地点上下文与当前消息不匹配,请刷新后重试", true, 502);
|
|
10884
|
+
raw = mergeSnapshotLocationContext(raw, context);
|
|
10885
|
+
}
|
|
10886
|
+
const detail = snapshotDetailFromChatRaw(raw, {
|
|
10887
|
+
itemUid: reference.recordUid,
|
|
10888
|
+
textContent: reference.textContent,
|
|
10889
|
+
sendAtMillis: reference.sendAtMillis
|
|
10890
|
+
});
|
|
10891
|
+
if (detail.itemUid !== reference.recordUid) throw new ArkmePluginError("message-snapshot-detail-mismatch", "快记详情与当前消息不匹配,请刷新后重试", true, 502);
|
|
10892
|
+
return detail;
|
|
10893
|
+
}
|
|
10894
|
+
async saveMessageLocation(sourceRef, itemUid, location, recordVersion, options = {}) {
|
|
10895
|
+
const session = await this.runtime.requireSession();
|
|
10896
|
+
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
10897
|
+
const recordUid = itemUid.trim();
|
|
10898
|
+
if (recordUid === "" || ![
|
|
10899
|
+
"private_chat",
|
|
10900
|
+
"group_chat",
|
|
10901
|
+
"send_to_self",
|
|
10902
|
+
"default_category",
|
|
10903
|
+
"topic"
|
|
10904
|
+
].includes(source.kind)) throw new ArkmePluginError("message-location-target-invalid", "当前消息不能写入位置快照", false, 400);
|
|
10905
|
+
const latitude = location.latitude;
|
|
10906
|
+
const longitude = location.longitude;
|
|
10907
|
+
if (!Number.isFinite(latitude) || latitude < -90 || latitude > 90 || !Number.isFinite(longitude) || longitude < -180 || longitude > 180) throw new ArkmePluginError("message-location-invalid", "位置坐标无效", false, 400);
|
|
10908
|
+
const altitude = location.altitudeMeters;
|
|
10909
|
+
const speed = location.speedMetersPerSecond;
|
|
10910
|
+
const accuracy = location.accuracyMeters;
|
|
10911
|
+
await this.runtime.authenticatedPost("/api/v1/records/location/set", {
|
|
10912
|
+
record_uid: recordUid,
|
|
10913
|
+
...recordVersion === void 0 || recordVersion <= 0 ? {} : { expected_record_version: Math.trunc(recordVersion) },
|
|
10914
|
+
location: {
|
|
10915
|
+
source_kind: 1,
|
|
10916
|
+
lat: latitude,
|
|
10917
|
+
lon: longitude,
|
|
10918
|
+
...altitude === void 0 || !Number.isFinite(altitude) ? {} : { alt: altitude },
|
|
10919
|
+
...speed === void 0 || !Number.isFinite(speed) || speed < 0 ? {} : { speed },
|
|
10920
|
+
...accuracy === void 0 || !Number.isFinite(accuracy) || accuracy < 0 ? {} : { accuracy },
|
|
10921
|
+
captured_at: Math.max(1, Math.trunc(location.capturedAtMillis))
|
|
10922
|
+
}
|
|
10923
|
+
}, session, options.signal);
|
|
10924
|
+
}
|
|
9880
10925
|
async rawChatMembers(chatSessionUid, activeOnly, session, signal) {
|
|
9881
10926
|
return listValue$16((await this.runtime.authenticatedChatPost("/api/v1/chats/members/list", {
|
|
9882
10927
|
chat_session_uid: chatSessionUid,
|
|
9883
10928
|
active_only: activeOnly
|
|
9884
10929
|
}, session, signal)).items).map(objectValue$1);
|
|
9885
10930
|
}
|
|
9886
|
-
async projectChatMembers(chatSessionUid, rawItems, session,
|
|
10931
|
+
async projectChatMembers(chatSessionUid, rawItems, session, options) {
|
|
9887
10932
|
const userIds = rawItems.map((item) => Math.trunc(numberValue$16(item.user_id))).filter((userId) => Number.isSafeInteger(userId) && userId > 0);
|
|
9888
|
-
const [profiles, viewerLabels] = await Promise.all([this.profile.publicProfileSummariesByUserIds(userIds, session, signal).catch(() => /* @__PURE__ */ new Map()), includeViewerLabels ? this.source.privateDisplayNamesByUserIds(userIds, { ...signal === void 0 ? {} : { signal } }).catch(() => /* @__PURE__ */ new Map()) : Promise.resolve(/* @__PURE__ */ new Map())]);
|
|
10933
|
+
const [profiles, viewerLabels] = await Promise.all([this.profile.publicProfileSummariesByUserIds(userIds, session, options.signal).catch(() => /* @__PURE__ */ new Map()), options.includeViewerLabels ? this.source.privateDisplayNamesByUserIds(userIds, { ...options.signal === void 0 ? {} : { signal: options.signal } }).catch(() => /* @__PURE__ */ new Map()) : Promise.resolve(/* @__PURE__ */ new Map())]);
|
|
9889
10934
|
const members = [];
|
|
9890
10935
|
for (const item of rawItems) {
|
|
9891
10936
|
const userId = Math.trunc(numberValue$16(item.user_id));
|
|
9892
10937
|
if (!Number.isSafeInteger(userId) || userId <= 0) continue;
|
|
9893
10938
|
const profile = profiles.get(userId);
|
|
9894
|
-
const { displayName, memberName, secondaryName } =
|
|
9895
|
-
userId,
|
|
9896
|
-
remarkCandidates: [],
|
|
9897
|
-
memberNameCandidates: [item.display_name_snapshot],
|
|
9898
|
-
userNameCandidates: [
|
|
9899
|
-
viewerLabels.get(userId),
|
|
9900
|
-
item.remark,
|
|
9901
|
-
profile?.displayName
|
|
9902
|
-
]
|
|
9903
|
-
});
|
|
10939
|
+
const { displayName, memberName, secondaryName } = projectChatMemberDisplayNames(item, userId, viewerLabels.get(userId), profile?.displayName);
|
|
9904
10940
|
const role = chatMemberRole$1(item.role);
|
|
9905
10941
|
const status = chatMemberStatus$1(item.status);
|
|
9906
10942
|
const extra = parsedObject(item.extra);
|
|
9907
10943
|
members.push({
|
|
9908
10944
|
memberRef: await this.sealChatMemberRef(session.userId, chatSessionUid, userId),
|
|
10945
|
+
...options.includeHumanMentionRefs && status === "active" && userId !== session.userId ? { mentionRef: await this.sealChatHumanMentionRef(session.userId, chatSessionUid, userId, displayName) } : {},
|
|
9909
10946
|
displayName,
|
|
9910
10947
|
...memberName === "" ? {} : { memberName },
|
|
9911
10948
|
...secondaryName === "" ? {} : { secondaryName },
|
|
@@ -9938,6 +10975,7 @@ var ChatService = class {
|
|
|
9938
10975
|
if (uid === "") continue;
|
|
9939
10976
|
const relationUid = stringValue$1(relation.rel_uid).trim();
|
|
9940
10977
|
const senderUserId = Math.trunc(numberValue$16(relation.sender_user_id));
|
|
10978
|
+
const recordOwnerUserId = chatRecordOwnerUserId(relation, record, payload, senderUserId);
|
|
9941
10979
|
const aiPolish = this.aiPolish.timelineAiPolish(record, payload);
|
|
9942
10980
|
const sendAtMillis = numberValue$16(relation.attach_at ?? payload.send_at);
|
|
9943
10981
|
const forwardRecords = await this.chatForwardRecordsPreview(item, session.userId, sendAtMillis);
|
|
@@ -9945,16 +10983,22 @@ var ChatService = class {
|
|
|
9945
10983
|
viewerUserId: session.userId,
|
|
9946
10984
|
chatSessionUid: source.ownerRef,
|
|
9947
10985
|
relationUid,
|
|
9948
|
-
recordOwnerUserId
|
|
10986
|
+
recordOwnerUserId,
|
|
9949
10987
|
recordUid: uid,
|
|
9950
10988
|
senderUserId,
|
|
9951
|
-
sequence: integerLikeValue
|
|
10989
|
+
sequence: integerLikeValue(relation.seq),
|
|
9952
10990
|
signingKey
|
|
9953
10991
|
});
|
|
9954
10992
|
const rawAgentSource = timelineAgentSource(relation, record, payload);
|
|
9955
10993
|
const agentSource = senderUserId === session.userId ? this.arko.currentUserAgentSourceFallback(session.userId, rawAgentSource) : rawAgentSource;
|
|
9956
10994
|
const contentBlocks = this.media.richContentBlocks(item, session.userId);
|
|
9957
10995
|
const senderName = stringValue$1(relation.display_name_snapshot).trim() || "Arkme用户";
|
|
10996
|
+
const captureContext = timelineCaptureContext({
|
|
10997
|
+
...record,
|
|
10998
|
+
...payload
|
|
10999
|
+
});
|
|
11000
|
+
const recordDurationMillis = positiveNumberValue$1(payload.record_duration_millis, record.record_duration_millis, payload.recordDurationMillis, record.recordDurationMillis, payload.cost_mill_sec, record.cost_mill_sec, payload.costMillSec, record.costMillSec);
|
|
11001
|
+
const editDurationMillis = positiveNumberValue$1(payload.edit_duration_millis, record.edit_duration_millis, payload.editDurationMillis, record.editDurationMillis, payload.incr_cost_mill_sec, record.incr_cost_mill_sec, payload.incrCostMillSec, record.incrCostMillSec);
|
|
9958
11002
|
const itemIndex = items.push({
|
|
9959
11003
|
itemUid: uid,
|
|
9960
11004
|
...source.kind !== "group_chat" || relationUid === "" || senderUserId === session.userId ? {} : { messageRef: this.sealMessageRef(session.userId, source.ownerRef, relationUid, signingKey) },
|
|
@@ -9964,7 +11008,7 @@ var ChatService = class {
|
|
|
9964
11008
|
sourceOwnerRef: source.ownerRef,
|
|
9965
11009
|
chatSessionUid: source.ownerRef,
|
|
9966
11010
|
relationUid,
|
|
9967
|
-
recordOwnerUserId
|
|
11011
|
+
recordOwnerUserId,
|
|
9968
11012
|
recordUid: uid,
|
|
9969
11013
|
senderUserId,
|
|
9970
11014
|
senderName,
|
|
@@ -9991,8 +11035,9 @@ var ChatService = class {
|
|
|
9991
11035
|
displayKind: numberValue$16(payload.display_kind),
|
|
9992
11036
|
version: numberValue$16(payload.version ?? record.version),
|
|
9993
11037
|
updateAtMillis: numberValue$16(payload.update_at ?? record.update_at),
|
|
9994
|
-
recordDurationMillis:
|
|
9995
|
-
editDurationMillis:
|
|
11038
|
+
...recordDurationMillis === void 0 ? {} : { recordDurationMillis },
|
|
11039
|
+
...editDurationMillis === void 0 ? {} : { editDurationMillis },
|
|
11040
|
+
...captureContext === void 0 ? {} : { captureContext },
|
|
9996
11041
|
contentBlocks,
|
|
9997
11042
|
...forwardRecords === void 0 ? {} : { forwardRecords },
|
|
9998
11043
|
...sharedRecording === void 0 ? {} : { sharedRecording }
|
|
@@ -10015,11 +11060,12 @@ var ChatService = class {
|
|
|
10015
11060
|
chatSessionUid,
|
|
10016
11061
|
targetUserId
|
|
10017
11062
|
});
|
|
10018
|
-
|
|
11063
|
+
const signature = createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(encoded).digest("base64url");
|
|
11064
|
+
return `${CHAT_MEMBER_REF_PREFIX}.${encoded}.${signature}`;
|
|
10019
11065
|
}
|
|
10020
11066
|
async openChatMemberRef(memberRef, expectedViewerUserId, expectedChatSessionUid) {
|
|
10021
11067
|
const parts = memberRef.trim().split(".");
|
|
10022
|
-
if (parts.length !== 3 || parts[0] !==
|
|
11068
|
+
if (parts.length !== 3 || parts[0] !== CHAT_MEMBER_REF_PREFIX) throw new ArkmePluginError("chat-member-ref-invalid", "聊天成员引用无效", false);
|
|
10023
11069
|
const encoded = parts[1] ?? "";
|
|
10024
11070
|
const supplied = Buffer.from(parts[2] ?? "", "base64url");
|
|
10025
11071
|
const expected = createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(encoded).digest();
|
|
@@ -10039,6 +11085,42 @@ var ChatService = class {
|
|
|
10039
11085
|
if (raw.version !== 1 || result.viewerUserId !== expectedViewerUserId || result.chatSessionUid !== expectedChatSessionUid || !Number.isSafeInteger(result.targetUserId) || result.targetUserId <= 0) throw new ArkmePluginError("chat-member-ref-invalid", "聊天成员引用与当前账号或会话不匹配", false, 403);
|
|
10040
11086
|
return result;
|
|
10041
11087
|
}
|
|
11088
|
+
async sealChatHumanMentionRef(viewerUserId, chatSessionUid, targetUserId, displayNameSnapshot) {
|
|
11089
|
+
const normalizedDisplayNameSnapshot = normalizedJoinDisplayName(displayNameSnapshot);
|
|
11090
|
+
if (normalizedDisplayNameSnapshot === "") throw new ArkmePluginError("chat-mention-ref-invalid", "真人 mention 展示名无效", false);
|
|
11091
|
+
const encoded = encodeOpaqueJson$6({
|
|
11092
|
+
version: 1,
|
|
11093
|
+
viewerUserId,
|
|
11094
|
+
chatSessionUid,
|
|
11095
|
+
targetUserId,
|
|
11096
|
+
displayNameSnapshot: normalizedDisplayNameSnapshot
|
|
11097
|
+
});
|
|
11098
|
+
const signature = createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(`${CHAT_HUMAN_MENTION_REF_PREFIX}.${encoded}`).digest("base64url");
|
|
11099
|
+
return `${CHAT_HUMAN_MENTION_REF_PREFIX}.${encoded}.${signature}`;
|
|
11100
|
+
}
|
|
11101
|
+
async openChatHumanMentionRef(mentionRef, expectedViewerUserId, expectedChatSessionUid) {
|
|
11102
|
+
const parts = mentionRef.trim().split(".");
|
|
11103
|
+
if (parts.length !== 3 || parts[0] !== CHAT_HUMAN_MENTION_REF_PREFIX) throw new ArkmePluginError("chat-mention-ref-invalid", "真人 mention 引用无效", false);
|
|
11104
|
+
const encoded = parts[1] ?? "";
|
|
11105
|
+
const supplied = Buffer.from(parts[2] ?? "", "base64url");
|
|
11106
|
+
const expected = createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(`${CHAT_HUMAN_MENTION_REF_PREFIX}.${encoded}`).digest();
|
|
11107
|
+
if (supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) throw new ArkmePluginError("chat-mention-ref-invalid", "真人 mention 引用无效", false);
|
|
11108
|
+
let raw;
|
|
11109
|
+
try {
|
|
11110
|
+
raw = objectValue$1(decodeOpaqueJson$5(encoded));
|
|
11111
|
+
} catch (error) {
|
|
11112
|
+
throw new ArkmePluginError("chat-mention-ref-invalid", "真人 mention 引用无效", false, 400, { cause: error });
|
|
11113
|
+
}
|
|
11114
|
+
const result = {
|
|
11115
|
+
version: 1,
|
|
11116
|
+
viewerUserId: Math.trunc(numberValue$16(raw.viewerUserId)),
|
|
11117
|
+
chatSessionUid: stringValue$1(raw.chatSessionUid).trim(),
|
|
11118
|
+
targetUserId: Math.trunc(numberValue$16(raw.targetUserId)),
|
|
11119
|
+
displayNameSnapshot: normalizedJoinDisplayName(raw.displayNameSnapshot)
|
|
11120
|
+
};
|
|
11121
|
+
if (raw.version !== 1 || result.viewerUserId !== expectedViewerUserId || result.chatSessionUid !== expectedChatSessionUid || !Number.isSafeInteger(result.targetUserId) || result.targetUserId <= 0 || result.displayNameSnapshot === "") throw new ArkmePluginError("chat-mention-ref-invalid", "真人 mention 引用与当前账号或会话不匹配", false, 403);
|
|
11122
|
+
return result;
|
|
11123
|
+
}
|
|
10042
11124
|
messageActionRefPayload(input) {
|
|
10043
11125
|
const contentBlocks = input.contentBlocks ?? [];
|
|
10044
11126
|
const fileNames = contentBlocks.filter((block) => block.kind === "file" && block.fileName.trim() !== "").slice(0, 5).map((block) => block.fileName.trim().slice(0, 256));
|
|
@@ -39417,7 +40499,7 @@ var CommunityService = class {
|
|
|
39417
40499
|
//#region src/services/extension-review-service.ts
|
|
39418
40500
|
const ARKME_EXTENSION_REVIEW_REF_TTL_MILLIS = 1800 * 1e3;
|
|
39419
40501
|
const MAX_ARKME_EXTENSION_REVIEW_REFS = 4096;
|
|
39420
|
-
function safeFailureMessage$
|
|
40502
|
+
function safeFailureMessage$3(error) {
|
|
39421
40503
|
if (error instanceof ArkmePluginError) return error.message;
|
|
39422
40504
|
if (error instanceof Error && error.message.trim() !== "") return error.message;
|
|
39423
40505
|
return "未知错误";
|
|
@@ -39545,7 +40627,7 @@ var ExtensionReviewService = class {
|
|
|
39545
40627
|
await this.runtime.stateStore.removeExtensionReviewOperation(userId, operation.clientMutationId);
|
|
39546
40628
|
throw new ArkmePluginError("extension-review-registry-rejected", `评论已写入首页,但市集未接受:${error.message}`, false, error.httpStatus, { cause: error });
|
|
39547
40629
|
}
|
|
39548
|
-
await this.runtime.stateStore.markExtensionReviewOperation(userId, operation.clientMutationId, "failed", safeFailureMessage$
|
|
40630
|
+
await this.runtime.stateStore.markExtensionReviewOperation(userId, operation.clientMutationId, "failed", safeFailureMessage$3(error));
|
|
39549
40631
|
throw new ArkmePluginError("extension-review-registry-pending", "评论已写入首页,但同步到扩展详情失败;请保留当前内容并重试", true, 503, { cause: error });
|
|
39550
40632
|
}
|
|
39551
40633
|
const authors = await this.extensionAuthors([result.review.user_id], signal);
|
|
@@ -39689,7 +40771,7 @@ function compactAiPolishActorLabel(value) {
|
|
|
39689
40771
|
const characters = [...new Intl.Segmenter("zh-CN", { granularity: "grapheme" }).segment(normalized)].map((segment) => segment.segment);
|
|
39690
40772
|
return characters.length <= 4 ? normalized : characters.slice(0, 4).join("") + "…";
|
|
39691
40773
|
}
|
|
39692
|
-
function safeFailureMessage$
|
|
40774
|
+
function safeFailureMessage$2(error) {
|
|
39693
40775
|
if (error instanceof ArkmePluginError) return error.message;
|
|
39694
40776
|
if (error instanceof Error && error.message.trim() !== "") return error.message;
|
|
39695
40777
|
return "未知错误";
|
|
@@ -40044,7 +41126,7 @@ var GroupAiPolishService = class {
|
|
|
40044
41126
|
polished = this.aiPolishTextResult(data);
|
|
40045
41127
|
} catch (error) {
|
|
40046
41128
|
const sent = await this.chat.sendChatSourceTextRaw(sourceRef, chatSessionUid, originalText, recordUid, relationUid, session, void 0, void 0, options.signal, options);
|
|
40047
|
-
return this.withFailedAiPolishRetry(sent, sourceRef, chatSessionUid, relationUid, recordUid, originalText, 1, session.userId, safeFailureMessage$
|
|
41129
|
+
return this.withFailedAiPolishRetry(sent, sourceRef, chatSessionUid, relationUid, recordUid, originalText, 1, session.userId, safeFailureMessage$2(error));
|
|
40048
41130
|
}
|
|
40049
41131
|
if (polished.state === 1 && polished.action === 1 && polished.polishedText !== "") {
|
|
40050
41132
|
const activeRule = config.rules.find((rule) => rule.ruleUid === polished.ruleUid);
|
|
@@ -40938,9 +42020,7 @@ var InterwovenService = class {
|
|
|
40938
42020
|
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
40939
42021
|
if (source.kind !== "private_chat") throw new ArkmePluginError("interwoven-source-invalid", "交织瞬间仅支持普通私聊", false, 400);
|
|
40940
42022
|
const reference = await this.openInterwovenMomentRef(momentRef, session.userId, source.ownerRef);
|
|
40941
|
-
|
|
40942
|
-
if (!booleanValue$4((await this.runtime.authenticatedAuthPost("/api/v1/auth/able-func", { func_type: 12 }, session, signal)).able)) throw new ArkmePluginError("interwoven-disabled", "交织瞬间能力当前未开放", false, 403);
|
|
40943
|
-
await this.assertHumanPrivateSource(source, session, signal);
|
|
42023
|
+
await this.assertInterwovenOperationAllowed(source, session, signal);
|
|
40944
42024
|
if (reference.detailMode === "owner_payload") return {
|
|
40945
42025
|
momentId: reference.momentId,
|
|
40946
42026
|
groupName: reference.groupName,
|
|
@@ -40981,6 +42061,29 @@ var InterwovenService = class {
|
|
|
40981
42061
|
degraded: status !== 1 || textContent === ""
|
|
40982
42062
|
};
|
|
40983
42063
|
}
|
|
42064
|
+
async relatedQuickNoteLocator(sourceRef, momentRef, signal) {
|
|
42065
|
+
const session = await this.runtime.requireSession();
|
|
42066
|
+
const normalizedSourceRef = sourceRef.trim();
|
|
42067
|
+
const source = await this.source.openSourceRef(normalizedSourceRef, session.userId);
|
|
42068
|
+
if (source.kind !== "private_chat") throw new ArkmePluginError("interwoven-source-invalid", "交织瞬间仅支持普通私聊", false, 400);
|
|
42069
|
+
const reference = await this.openInterwovenMomentRef(momentRef, session.userId, source.ownerRef);
|
|
42070
|
+
await this.assertInterwovenOperationAllowed(source, session, signal);
|
|
42071
|
+
return {
|
|
42072
|
+
viewerUserId: session.userId,
|
|
42073
|
+
sourceRef: normalizedSourceRef,
|
|
42074
|
+
sourceOwnerRef: source.ownerRef,
|
|
42075
|
+
contextType: reference.sourceChatSessionUid === "" ? "record" : "chat",
|
|
42076
|
+
recordUid: reference.recordUid,
|
|
42077
|
+
recordOwnerUserId: reference.recordOwnerUserId,
|
|
42078
|
+
chatSessionUid: reference.sourceChatSessionUid
|
|
42079
|
+
};
|
|
42080
|
+
}
|
|
42081
|
+
async assertInterwovenOperationAllowed(source, session, signal) {
|
|
42082
|
+
if (source.kind !== "private_chat") throw new ArkmePluginError("interwoven-source-invalid", "交织瞬间仅支持普通私聊", false, 400);
|
|
42083
|
+
if (!this.runtime.config.interwovenMomentsEnabled) throw new ArkmePluginError("interwoven-disabled", "交织瞬间能力当前未开启", false, 403);
|
|
42084
|
+
if (!booleanValue$4((await this.runtime.authenticatedAuthPost("/api/v1/auth/able-func", { func_type: 12 }, session, signal)).able)) throw new ArkmePluginError("interwoven-disabled", "交织瞬间能力当前未开放", false, 403);
|
|
42085
|
+
await this.assertHumanPrivateSource(source, session, signal);
|
|
42086
|
+
}
|
|
40984
42087
|
async assertHumanPrivateSource(source, session, signal) {
|
|
40985
42088
|
const detail = await this.runtime.authenticatedChatPost("/api/v1/chats/detail", { chat_session_uid: source.ownerRef }, session, signal);
|
|
40986
42089
|
const chatSession = objectValue$1(detail.session);
|
|
@@ -42994,416 +44097,327 @@ var ProfileService = class {
|
|
|
42994
44097
|
}
|
|
42995
44098
|
};
|
|
42996
44099
|
//#endregion
|
|
42997
|
-
//#region src/services/
|
|
44100
|
+
//#region src/services/related-quick-note-service.ts
|
|
44101
|
+
const RELATED_QUICK_NOTE_LIMIT = 20;
|
|
44102
|
+
const RELATED_QUICK_NOTE_REF_TTL_MS = 720 * 60 * 1e3;
|
|
44103
|
+
const RELATED_QUICK_NOTE_REF_CAP = 1e3;
|
|
42998
44104
|
function numberValue$6(value) {
|
|
42999
|
-
|
|
43000
|
-
}
|
|
43001
|
-
function listValue$7(value) {
|
|
43002
|
-
return Array.isArray(value) ? value : [];
|
|
43003
|
-
}
|
|
43004
|
-
const DSH_AGENT_INPUT_CREATION_SOURCE = 3;
|
|
43005
|
-
const MAX_DEFAULT_CATEGORY_FILTER_BACKFILL_PAGES = 5;
|
|
43006
|
-
function integerLikeValue(value) {
|
|
43007
|
-
if (typeof value === "number" && Number.isFinite(value)) return Math.trunc(value);
|
|
44105
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
43008
44106
|
if (typeof value === "string" && value.trim() !== "") {
|
|
43009
44107
|
const parsed = Number(value.trim());
|
|
43010
|
-
if (Number.isFinite(parsed)) return
|
|
44108
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
43011
44109
|
}
|
|
43012
44110
|
return 0;
|
|
43013
44111
|
}
|
|
43014
|
-
function
|
|
44112
|
+
function firstString(item, keys) {
|
|
44113
|
+
for (const key of keys) {
|
|
44114
|
+
const value = stringValue$1(item[key]).trim();
|
|
44115
|
+
if (value !== "") return value;
|
|
44116
|
+
}
|
|
44117
|
+
return "";
|
|
44118
|
+
}
|
|
44119
|
+
function firstPositiveInteger(item, keys) {
|
|
44120
|
+
for (const key of keys) {
|
|
44121
|
+
const value = Math.trunc(numberValue$6(item[key]));
|
|
44122
|
+
if (Number.isSafeInteger(value) && value > 0) return value;
|
|
44123
|
+
}
|
|
44124
|
+
return 0;
|
|
44125
|
+
}
|
|
44126
|
+
function recordCore(raw) {
|
|
43015
44127
|
const item = objectValue$1(raw);
|
|
43016
|
-
|
|
43017
|
-
return integerLikeValue(item.creation_source ?? item.creationSource ?? core.creation_source ?? core.creationSource);
|
|
44128
|
+
return objectValue$1(item.record_core ?? item.recordCore);
|
|
43018
44129
|
}
|
|
43019
|
-
function
|
|
43020
|
-
|
|
44130
|
+
function recordUid(raw) {
|
|
44131
|
+
const item = objectValue$1(raw);
|
|
44132
|
+
const core = recordCore(raw);
|
|
44133
|
+
return firstString(item, [
|
|
44134
|
+
"record_uid",
|
|
44135
|
+
"recordUid",
|
|
44136
|
+
"uid",
|
|
44137
|
+
"target_record_uid",
|
|
44138
|
+
"targetRecordUid"
|
|
44139
|
+
]) || firstString(core, [
|
|
44140
|
+
"record_uid",
|
|
44141
|
+
"recordUid",
|
|
44142
|
+
"uid"
|
|
44143
|
+
]);
|
|
43021
44144
|
}
|
|
43022
|
-
function
|
|
43023
|
-
|
|
43024
|
-
|
|
43025
|
-
return
|
|
44145
|
+
function recordOwnerUserId(raw) {
|
|
44146
|
+
const item = objectValue$1(raw);
|
|
44147
|
+
const core = recordCore(raw);
|
|
44148
|
+
return firstPositiveInteger(item, [
|
|
44149
|
+
"record_owner_user_id",
|
|
44150
|
+
"recordOwnerUserId",
|
|
44151
|
+
"owner_user_id",
|
|
44152
|
+
"ownerUserId"
|
|
44153
|
+
]) || firstPositiveInteger(core, [
|
|
44154
|
+
"record_owner_user_id",
|
|
44155
|
+
"recordOwnerUserId",
|
|
44156
|
+
"owner_user_id",
|
|
44157
|
+
"ownerUserId"
|
|
44158
|
+
]);
|
|
43026
44159
|
}
|
|
43027
|
-
|
|
44160
|
+
function matchesRecordIdentity(raw, expectedUid, expectedOwnerUserId) {
|
|
44161
|
+
const uidKeys = [
|
|
44162
|
+
"record_uid",
|
|
44163
|
+
"recordUid",
|
|
44164
|
+
"uid",
|
|
44165
|
+
"target_record_uid",
|
|
44166
|
+
"targetRecordUid"
|
|
44167
|
+
];
|
|
44168
|
+
const ownerKeys = [
|
|
44169
|
+
"record_owner_user_id",
|
|
44170
|
+
"recordOwnerUserId",
|
|
44171
|
+
"owner_user_id",
|
|
44172
|
+
"ownerUserId"
|
|
44173
|
+
];
|
|
44174
|
+
const identities = [objectValue$1(raw), recordCore(raw)];
|
|
44175
|
+
const uids = identities.flatMap((item) => uidKeys.map((key) => stringValue$1(item[key]).trim()).filter((value) => value !== ""));
|
|
44176
|
+
const ownerUserIds = identities.flatMap((item) => ownerKeys.map((key) => Math.trunc(numberValue$6(item[key]))).filter((value) => Number.isSafeInteger(value) && value > 0));
|
|
44177
|
+
return uids.length > 0 && ownerUserIds.length > 0 && uids.every((value) => value === expectedUid) && ownerUserIds.every((value) => value === expectedOwnerUserId);
|
|
44178
|
+
}
|
|
44179
|
+
function millisValue(value) {
|
|
44180
|
+
const parsed = Math.trunc(numberValue$6(value));
|
|
44181
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) return 0;
|
|
44182
|
+
return parsed > 1e11 ? parsed : parsed * 1e3;
|
|
44183
|
+
}
|
|
44184
|
+
function listValue$7(value) {
|
|
44185
|
+
return Array.isArray(value) ? value : [];
|
|
44186
|
+
}
|
|
44187
|
+
function descriptorFromRaw(raw) {
|
|
44188
|
+
const item = objectValue$1(raw);
|
|
44189
|
+
const core = recordCore(raw);
|
|
44190
|
+
const uid = recordUid(raw);
|
|
44191
|
+
const ownerUserId = recordOwnerUserId(raw);
|
|
44192
|
+
if (uid === "" || ownerUserId <= 0) return void 0;
|
|
44193
|
+
const authorUserId = firstPositiveInteger(item, [
|
|
44194
|
+
"author_user_id",
|
|
44195
|
+
"authorUserId",
|
|
44196
|
+
"creator_user_id",
|
|
44197
|
+
"creatorUserId"
|
|
44198
|
+
]) || firstPositiveInteger(core, ["creator_user_id", "creatorUserId"]) || ownerUserId;
|
|
44199
|
+
const senderName = firstString(item, [
|
|
44200
|
+
"author_name",
|
|
44201
|
+
"authorName",
|
|
44202
|
+
"author_nickname",
|
|
44203
|
+
"authorNickname",
|
|
44204
|
+
"sender_name",
|
|
44205
|
+
"senderName",
|
|
44206
|
+
"nickname",
|
|
44207
|
+
"nick_name"
|
|
44208
|
+
]);
|
|
44209
|
+
const title = firstString(item, ["title"]) || firstString(core, ["title"]);
|
|
44210
|
+
const textPreview = firstString(item, [
|
|
44211
|
+
"text_preview",
|
|
44212
|
+
"textPreview",
|
|
44213
|
+
"text",
|
|
44214
|
+
"content",
|
|
44215
|
+
"text_content",
|
|
44216
|
+
"textContent"
|
|
44217
|
+
]) || firstString(core, ["text_content", "textContent"]);
|
|
44218
|
+
const sendAtMillis = millisValue(item.send_at ?? item.sendAt ?? core.send_at ?? core.sendAt);
|
|
44219
|
+
const sourceLabel = firstString(item, ["source_label", "sourceLabel"]);
|
|
44220
|
+
return {
|
|
44221
|
+
recordUid: uid,
|
|
44222
|
+
recordOwnerUserId: ownerUserId,
|
|
44223
|
+
authorUserId,
|
|
44224
|
+
senderName: senderName.slice(0, 200),
|
|
44225
|
+
sendAtMillis,
|
|
44226
|
+
title: title.slice(0, 500),
|
|
44227
|
+
textPreview: textPreview.slice(0, 2e3),
|
|
44228
|
+
...sourceLabel === "" ? {} : { sourceLabel: sourceLabel.slice(0, 200) }
|
|
44229
|
+
};
|
|
44230
|
+
}
|
|
44231
|
+
var RelatedQuickNoteService = class {
|
|
43028
44232
|
runtime;
|
|
44233
|
+
record;
|
|
43029
44234
|
media;
|
|
43030
|
-
|
|
44235
|
+
profile;
|
|
43031
44236
|
privacy;
|
|
43032
|
-
|
|
44237
|
+
references = /* @__PURE__ */ new Map();
|
|
44238
|
+
constructor(runtime, record, media, profile, privacy = new ArkmePrivacyVisibilityService(runtime)) {
|
|
43033
44239
|
this.runtime = runtime;
|
|
44240
|
+
this.record = record;
|
|
43034
44241
|
this.media = media;
|
|
43035
|
-
this.
|
|
44242
|
+
this.profile = profile;
|
|
43036
44243
|
this.privacy = privacy;
|
|
43037
44244
|
}
|
|
43038
|
-
|
|
43039
|
-
|
|
43040
|
-
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
43041
|
-
const uid = itemUid.trim();
|
|
43042
|
-
if (uid === "") throw new ArkmePluginError("long-article-item-invalid", "长文记录标识无效", false);
|
|
43043
|
-
const data = await this.runtime.authenticatedPost("/api/v1/records/detail", { record_uid: uid }, session, signal);
|
|
43044
|
-
const core = objectValue$1(data.record_core);
|
|
43045
|
-
const recordUid = stringValue$1(core.record_uid).trim();
|
|
43046
|
-
const templateKind = numberValue$6(core.template_kind);
|
|
43047
|
-
const displayKind = numberValue$6(core.display_kind);
|
|
43048
|
-
if (recordUid !== uid || templateKind !== 8 && displayKind !== 1) throw new ArkmePluginError("long-article-not-found", "未找到可用的长文详情", false, 404);
|
|
43049
|
-
const originContainerRef = stringValue$1(core.origin_container_ref).trim();
|
|
43050
|
-
if (source.kind === "topic") {
|
|
43051
|
-
if (stringValue$1(objectValue$1(data.topic_core).topic_uid).trim() !== source.ownerRef) throw new ArkmePluginError("long-article-source-mismatch", "长文不属于当前会话", false, 403);
|
|
43052
|
-
} else if (source.kind === "private_chat" || source.kind === "group_chat") {
|
|
43053
|
-
if (originContainerRef !== source.ownerRef) throw new ArkmePluginError("long-article-source-mismatch", "长文不属于当前会话", false, 403);
|
|
43054
|
-
} else if (numberValue$6(core.owner_user_id) !== session.userId) throw new ArkmePluginError("long-article-source-mismatch", "长文不属于当前会话", false, 403);
|
|
43055
|
-
const recordDurationMillis = Math.max(0, Math.trunc(numberValue$6(core.record_duration_millis)));
|
|
43056
|
-
const editDurationMillis = Math.max(0, Math.trunc(numberValue$6(core.edit_duration_millis)));
|
|
43057
|
-
return {
|
|
43058
|
-
sourceRef,
|
|
43059
|
-
itemUid: recordUid,
|
|
43060
|
-
title: stringValue$1(core.title),
|
|
43061
|
-
textContent: stringValue$1(core.text_content),
|
|
43062
|
-
sendAtMillis: Math.trunc(numberValue$6(core.send_at)),
|
|
43063
|
-
updateAtMillis: Math.trunc(numberValue$6(core.update_at)),
|
|
43064
|
-
recordDurationMillis,
|
|
43065
|
-
editDurationMillis,
|
|
43066
|
-
thinkingDurationMillis: recordDurationMillis + editDurationMillis,
|
|
43067
|
-
version: Math.trunc(numberValue$6(core.version)),
|
|
43068
|
-
editable: numberValue$6(core.owner_user_id) === session.userId && numberValue$6(core.creator_user_id) === session.userId
|
|
43069
|
-
};
|
|
43070
|
-
}
|
|
43071
|
-
async updateLongArticle(sourceRef, itemUid, input) {
|
|
43072
|
-
if (this.runtime.config.richMediaSendEnabled === false) throw new ArkmePluginError("rich-content-disabled", "长文编辑已被插件配置关闭", false, 403);
|
|
43073
|
-
const session = await this.runtime.requireSession();
|
|
43074
|
-
const detail = await this.longArticleDetail(sourceRef, itemUid);
|
|
43075
|
-
const title = input.title.trim();
|
|
43076
|
-
const textContent = input.textContent.trim();
|
|
43077
|
-
const editDurationMillis = Math.max(0, Math.trunc(input.editDurationMillis));
|
|
43078
|
-
if (!detail.editable) throw new ArkmePluginError("long-article-not-editable", "只能编辑自己发布的长文", false, 403);
|
|
43079
|
-
if (title === "" || title.length > 100 || textContent === "" || textContent.length > 4e4 || !Number.isSafeInteger(input.version) || input.version <= 0 || input.version !== detail.version) throw new ArkmePluginError("long-article-update-invalid", "长文内容或版本无效,请刷新后重试", false, 409);
|
|
43080
|
-
await this.runtime.authenticatedPost("/api/v1/records/update", {
|
|
43081
|
-
record_uid: detail.itemUid,
|
|
43082
|
-
template_kind: 1,
|
|
43083
|
-
display_kind: 1,
|
|
43084
|
-
title,
|
|
43085
|
-
text_content: textContent,
|
|
43086
|
-
record_duration_millis: detail.recordDurationMillis,
|
|
43087
|
-
edit_duration_millis: editDurationMillis,
|
|
43088
|
-
version: detail.version
|
|
43089
|
-
}, session);
|
|
43090
|
-
return await this.longArticleDetail(sourceRef, itemUid);
|
|
43091
|
-
}
|
|
43092
|
-
async getLongArticleDraft(sourceRef, itemUid) {
|
|
43093
|
-
const session = await this.runtime.requireSession();
|
|
43094
|
-
await this.source.openSourceRef(sourceRef, session.userId);
|
|
43095
|
-
return await this.runtime.stateStore.getLongArticleDraft(session.userId, sourceRef, itemUid?.trim() || void 0);
|
|
43096
|
-
}
|
|
43097
|
-
async putLongArticleDraft(draft) {
|
|
43098
|
-
const session = await this.runtime.requireSession();
|
|
43099
|
-
await this.source.openSourceRef(draft.sourceRef, session.userId);
|
|
43100
|
-
const itemUid = draft.itemUid?.trim() || void 0;
|
|
43101
|
-
if (draft.title.length > 100 || draft.textContent.length > 4e4 || draft.durationMillis < 0) throw new ArkmePluginError("long-article-draft-invalid", "长文草稿内容无效", false);
|
|
43102
|
-
await this.runtime.stateStore.putLongArticleDraft(session.userId, {
|
|
43103
|
-
sourceRef: draft.sourceRef,
|
|
43104
|
-
...itemUid === void 0 ? {} : { itemUid },
|
|
43105
|
-
title: draft.title,
|
|
43106
|
-
textContent: draft.textContent,
|
|
43107
|
-
durationMillis: Math.max(0, Math.trunc(draft.durationMillis)),
|
|
43108
|
-
updatedAtMillis: Date.now()
|
|
43109
|
-
});
|
|
43110
|
-
}
|
|
43111
|
-
async removeLongArticleDraft(sourceRef, itemUid) {
|
|
43112
|
-
const session = await this.runtime.requireSession();
|
|
43113
|
-
await this.source.openSourceRef(sourceRef, session.userId);
|
|
43114
|
-
await this.runtime.stateStore.removeLongArticleDraft(session.userId, sourceRef, itemUid?.trim() || void 0);
|
|
43115
|
-
}
|
|
43116
|
-
async cachedSnapshot() {
|
|
43117
|
-
const session = await this.runtime.requireSession();
|
|
43118
|
-
return await this.runtime.stateStore.cachedSnapshot(session.userId);
|
|
43119
|
-
}
|
|
43120
|
-
async queryCached(options) {
|
|
43121
|
-
const session = await this.runtime.requireSession();
|
|
43122
|
-
return await this.runtime.stateStore.queryCached(session.userId, options);
|
|
43123
|
-
}
|
|
43124
|
-
async refreshLatest() {
|
|
43125
|
-
await Promise.all([this.summary(), this.list(50)]);
|
|
43126
|
-
}
|
|
43127
|
-
async refreshSnapshot() {
|
|
43128
|
-
await this.refreshLatest();
|
|
43129
|
-
return await this.cachedSnapshot();
|
|
43130
|
-
}
|
|
43131
|
-
async summary() {
|
|
43132
|
-
const session = await this.runtime.requireSession();
|
|
43133
|
-
const data = await this.runtime.authenticatedPost("/api/v1/records/uncategorized/summary", {}, session);
|
|
43134
|
-
const summary = {
|
|
43135
|
-
recordCount: numberValue$6(data.record_count),
|
|
43136
|
-
wordsCount: numberValue$6(data.words_count ?? data.available_text_rune_count),
|
|
43137
|
-
totalSec: numberValue$6(data.total_sec ?? data.available_voice_duration_sec)
|
|
43138
|
-
};
|
|
43139
|
-
await this.runtime.stateStore.cacheSummary(session.userId, summary);
|
|
43140
|
-
return summary;
|
|
44245
|
+
dispose() {
|
|
44246
|
+
this.references.clear();
|
|
43141
44247
|
}
|
|
43142
|
-
async list(
|
|
44248
|
+
async list(locator, signal) {
|
|
43143
44249
|
const session = await this.runtime.requireSession();
|
|
43144
|
-
const
|
|
43145
|
-
const
|
|
43146
|
-
|
|
43147
|
-
|
|
43148
|
-
|
|
43149
|
-
|
|
43150
|
-
|
|
43151
|
-
|
|
43152
|
-
|
|
43153
|
-
|
|
43154
|
-
|
|
43155
|
-
|
|
43156
|
-
|
|
43157
|
-
|
|
43158
|
-
|
|
43159
|
-
const
|
|
43160
|
-
|
|
43161
|
-
|
|
43162
|
-
|
|
43163
|
-
|
|
43164
|
-
backendNextCursor = nextSendAt > 0 && nextUid !== "" ? {
|
|
43165
|
-
sendAtMillis: nextSendAt,
|
|
43166
|
-
recordUid: nextUid
|
|
43167
|
-
} : void 0;
|
|
43168
|
-
const filteredCount = rawPageItems.length - visiblePageItems.length;
|
|
43169
|
-
if (visibleRawItems.length >= normalizedLimit || !hasMore || backendNextCursor === void 0 || filteredCount === 0) break;
|
|
43170
|
-
requestCursor = backendNextCursor;
|
|
44250
|
+
const source = this.validLocator(locator, session.userId);
|
|
44251
|
+
const response = await this.runtime.authenticatedPost("/api/v1/records/related/query", {
|
|
44252
|
+
record_uid: source.recordUid,
|
|
44253
|
+
record_owner_user_id: source.recordOwnerUserId,
|
|
44254
|
+
context_type: source.contextType,
|
|
44255
|
+
...source.contextType === "chat" ? { chat_session_uid: source.chatSessionUid } : {},
|
|
44256
|
+
limit: RELATED_QUICK_NOTE_LIMIT
|
|
44257
|
+
}, session, signal);
|
|
44258
|
+
const excluded = /* @__PURE__ */ new Set([source.recordUid]);
|
|
44259
|
+
const lockedRecordUids = await this.privacy.lockedRecordUids(session, signal);
|
|
44260
|
+
const directItems = listValue$7(response.items ?? response.records);
|
|
44261
|
+
const candidates = this.relatedCandidates(response, directItems, excluded, lockedRecordUids);
|
|
44262
|
+
const missingUids = candidates.filter((candidate) => descriptorFromRaw(candidate.raw) === void 0).map((candidate) => candidate.uid);
|
|
44263
|
+
const hydratedByUid = /* @__PURE__ */ new Map();
|
|
44264
|
+
if (missingUids.length > 0) {
|
|
44265
|
+
const batch = await this.runtime.authenticatedDataPost("/api/v1/memo/batch-get-records", { record_uids: missingUids }, session, signal);
|
|
44266
|
+
for (const raw of listValue$7(batch.items)) {
|
|
44267
|
+
const uid = recordUid(raw);
|
|
44268
|
+
if (uid !== "" && !hydratedByUid.has(uid)) hydratedByUid.set(uid, raw);
|
|
44269
|
+
}
|
|
43171
44270
|
}
|
|
43172
|
-
const
|
|
43173
|
-
const
|
|
43174
|
-
const
|
|
43175
|
-
const
|
|
43176
|
-
const
|
|
43177
|
-
const
|
|
43178
|
-
|
|
43179
|
-
|
|
43180
|
-
|
|
44271
|
+
const descriptors = this.descriptorsFromItems(candidates.flatMap((candidate) => descriptorFromRaw(candidate.raw) === void 0 ? hydratedByUid.has(candidate.uid) ? [hydratedByUid.get(candidate.uid)] : [] : [candidate.raw]), excluded, lockedRecordUids);
|
|
44272
|
+
const profiles = await this.profile.publicProfileSummariesByUserIds(descriptors.map((item) => item.authorUserId), session, signal).catch(() => /* @__PURE__ */ new Map());
|
|
44273
|
+
const items = [];
|
|
44274
|
+
for (const descriptor of descriptors) {
|
|
44275
|
+
const profile = profiles.get(descriptor.authorUserId);
|
|
44276
|
+
const senderName = descriptor.senderName || profile?.displayName || (descriptor.authorUserId === session.userId ? "我" : "Arkme 用户");
|
|
44277
|
+
const senderAvatarRef = profile?.avatarUrl === void 0 ? void 0 : await this.profile.sealProfileImageRef(session.userId, descriptor.authorUserId);
|
|
44278
|
+
const relatedRef = await this.sealReference({
|
|
44279
|
+
viewerUserId: session.userId,
|
|
44280
|
+
sourceRef: source.sourceRef,
|
|
44281
|
+
sourceOwnerRef: source.sourceOwnerRef,
|
|
44282
|
+
recordUid: descriptor.recordUid,
|
|
44283
|
+
recordOwnerUserId: descriptor.recordOwnerUserId,
|
|
44284
|
+
senderName,
|
|
44285
|
+
...senderAvatarRef === void 0 ? {} : { senderAvatarRef }
|
|
43181
44286
|
});
|
|
43182
|
-
|
|
43183
|
-
|
|
43184
|
-
|
|
43185
|
-
|
|
43186
|
-
|
|
43187
|
-
|
|
43188
|
-
|
|
43189
|
-
|
|
43190
|
-
|
|
44287
|
+
items.push({
|
|
44288
|
+
relatedRef,
|
|
44289
|
+
senderName,
|
|
44290
|
+
...senderAvatarRef === void 0 ? {} : { senderAvatarRef },
|
|
44291
|
+
sendAtMillis: descriptor.sendAtMillis,
|
|
44292
|
+
title: descriptor.title,
|
|
44293
|
+
textPreview: descriptor.textPreview,
|
|
44294
|
+
...descriptor.sourceLabel === void 0 ? {} : { sourceLabel: descriptor.sourceLabel }
|
|
44295
|
+
});
|
|
44296
|
+
}
|
|
44297
|
+
return {
|
|
43191
44298
|
items,
|
|
43192
|
-
|
|
43193
|
-
...nextCursor === void 0 ? {} : { nextCursor }
|
|
43194
|
-
};
|
|
43195
|
-
await this.runtime.stateStore.cachePage(session.userId, page, cursor);
|
|
43196
|
-
return page;
|
|
43197
|
-
}
|
|
43198
|
-
async createText(recordUid, textContent) {
|
|
43199
|
-
const session = await this.runtime.requireSession();
|
|
43200
|
-
const normalizedUid = recordUid.trim();
|
|
43201
|
-
const normalizedText = textContent.trim();
|
|
43202
|
-
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(normalizedUid)) throw new ArkmePluginError("record-uid-invalid", "写入标识无效,请重试", false);
|
|
43203
|
-
if (normalizedText === "") throw new ArkmePluginError("record-text-empty", "请输入要发给自己的内容", false);
|
|
43204
|
-
if (normalizedText.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("record-text-too-long", `内容不能超过 ${this.runtime.config.maxTextLength} 个字符`, false);
|
|
43205
|
-
const now = Date.now();
|
|
43206
|
-
const pending = {
|
|
43207
|
-
recordUid: normalizedUid,
|
|
43208
|
-
textContent: normalizedText,
|
|
43209
|
-
createdAtMillis: now,
|
|
43210
|
-
sendAtMillis: now,
|
|
43211
|
-
attempts: 0
|
|
44299
|
+
total: items.length
|
|
43212
44300
|
};
|
|
43213
|
-
await this.runtime.stateStore.putPending(session.userId, pending);
|
|
43214
|
-
return await this.sendPending(session, pending);
|
|
43215
|
-
}
|
|
43216
|
-
async createTextForConversation(recordUid, textContent) {
|
|
43217
|
-
try {
|
|
43218
|
-
return {
|
|
43219
|
-
...await this.createText(recordUid, textContent),
|
|
43220
|
-
localState: "synced"
|
|
43221
|
-
};
|
|
43222
|
-
} catch (error) {
|
|
43223
|
-
const session = await this.runtime.requireSession();
|
|
43224
|
-
const pending = (await this.runtime.stateStore.listPending(session.userId)).find((item) => item.recordUid === recordUid);
|
|
43225
|
-
if (pending === void 0) throw error;
|
|
43226
|
-
return {
|
|
43227
|
-
recordUid,
|
|
43228
|
-
status: 0,
|
|
43229
|
-
localState: "failed",
|
|
43230
|
-
error: pending.lastError ?? safeFailureMessage$2(error)
|
|
43231
|
-
};
|
|
43232
|
-
}
|
|
43233
44301
|
}
|
|
43234
|
-
async
|
|
44302
|
+
async detail(sourceRef, relatedRef, signal) {
|
|
43235
44303
|
const session = await this.runtime.requireSession();
|
|
43236
|
-
const
|
|
43237
|
-
const
|
|
43238
|
-
|
|
43239
|
-
|
|
43240
|
-
if (
|
|
43241
|
-
|
|
43242
|
-
const
|
|
43243
|
-
|
|
43244
|
-
|
|
43245
|
-
|
|
43246
|
-
|
|
43247
|
-
|
|
43248
|
-
}, session, void 0, {
|
|
43249
|
-
scope: this.runtime.requestScope(session.userId),
|
|
43250
|
-
key: `dsh-agent-input:${normalizedUid}`
|
|
44304
|
+
const reference = await this.openReference(relatedRef, session.userId, sourceRef.trim());
|
|
44305
|
+
const raw = await this.runtime.authenticatedPost("/api/v1/records/detail", { record_uid: reference.recordUid }, session, signal);
|
|
44306
|
+
if (!matchesRecordIdentity(raw, reference.recordUid, reference.recordOwnerUserId)) throw new ArkmePluginError("related-quick-note-detail-contract-invalid", "相关快记详情响应与所选快记不一致", true, 502);
|
|
44307
|
+
const lockedRecordUids = await this.privacy.lockedRecordUids(session, signal);
|
|
44308
|
+
if (arkmePrivacyLockedRecord(raw) || lockedRecordUids.has(reference.recordUid)) throw new ArkmePluginError("related-quick-note-private", "该相关快记不可查看", false, 403);
|
|
44309
|
+
const hydrated = await this.media.hydrateRecordMediaPage([raw], session, signal);
|
|
44310
|
+
const displayItems = hydrated.displayItemsByRecordUid.get(reference.recordUid);
|
|
44311
|
+
const mediaUnavailable = hydrated.unavailableRecordUids.has(reference.recordUid);
|
|
44312
|
+
const detail = this.record.recordTimelineItemFromRaw(raw, session.userId, {
|
|
44313
|
+
...displayItems === void 0 ? {} : { displayItems },
|
|
44314
|
+
...mediaUnavailable ? { mediaUnavailable: true } : {},
|
|
44315
|
+
isMe: reference.recordOwnerUserId === session.userId
|
|
43251
44316
|
});
|
|
43252
|
-
|
|
44317
|
+
if (detail.itemUid !== reference.recordUid) throw new ArkmePluginError("related-quick-note-detail-contract-invalid", "相关快记详情标识无效", true, 502);
|
|
43253
44318
|
return {
|
|
43254
|
-
|
|
43255
|
-
|
|
43256
|
-
|
|
43257
|
-
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
|
|
43261
|
-
|
|
43262
|
-
|
|
43263
|
-
|
|
43264
|
-
|
|
43265
|
-
|
|
43266
|
-
|
|
43267
|
-
|
|
43268
|
-
|
|
43269
|
-
|
|
43270
|
-
|
|
43271
|
-
|
|
43272
|
-
|
|
43273
|
-
|
|
43274
|
-
|
|
43275
|
-
|
|
43276
|
-
|
|
43277
|
-
|
|
43278
|
-
|
|
43279
|
-
|
|
43280
|
-
|
|
43281
|
-
file_asset_uid: asset.fileAssetUid,
|
|
43282
|
-
content_file_role: 1,
|
|
43283
|
-
render_role: 1,
|
|
43284
|
-
sort_order: index,
|
|
43285
|
-
file_name: asset.fileName
|
|
43286
|
-
}))
|
|
43287
|
-
},
|
|
43288
|
-
send_at: Date.now()
|
|
43289
|
-
}, session);
|
|
44319
|
+
relatedRef,
|
|
44320
|
+
senderName: reference.senderName,
|
|
44321
|
+
...reference.senderAvatarRef === void 0 ? {} : { avatarRef: reference.senderAvatarRef },
|
|
44322
|
+
isMe: reference.recordOwnerUserId === session.userId,
|
|
44323
|
+
sendAtMillis: detail.sendAtMillis,
|
|
44324
|
+
title: detail.title,
|
|
44325
|
+
textContent: detail.textContent,
|
|
44326
|
+
status: detail.status,
|
|
44327
|
+
...detail.recordVersion === void 0 ? {} : { recordVersion: detail.recordVersion },
|
|
44328
|
+
...detail.aiPolish === void 0 ? {} : { aiPolish: detail.aiPolish },
|
|
44329
|
+
...detail.templateKind === void 0 ? {} : { templateKind: detail.templateKind },
|
|
44330
|
+
...detail.displayKind === void 0 ? {} : { displayKind: detail.displayKind },
|
|
44331
|
+
...detail.version === void 0 ? {} : { version: detail.version },
|
|
44332
|
+
...detail.updateAtMillis === void 0 ? {} : { updateAtMillis: detail.updateAtMillis },
|
|
44333
|
+
...detail.recordDurationMillis === void 0 ? {} : { recordDurationMillis: detail.recordDurationMillis },
|
|
44334
|
+
...detail.editDurationMillis === void 0 ? {} : { editDurationMillis: detail.editDurationMillis },
|
|
44335
|
+
...detail.contentBlocks === void 0 ? {} : { contentBlocks: detail.contentBlocks },
|
|
44336
|
+
...detail.mediaUnavailable === void 0 ? {} : { mediaUnavailable: detail.mediaUnavailable },
|
|
44337
|
+
...detail.forwardRecords === void 0 ? {} : { forwardRecords: detail.forwardRecords }
|
|
44338
|
+
};
|
|
44339
|
+
}
|
|
44340
|
+
validLocator(locator, expectedViewerUserId) {
|
|
44341
|
+
const sourceRef = locator.sourceRef.trim();
|
|
44342
|
+
const sourceOwnerRef = locator.sourceOwnerRef.trim();
|
|
44343
|
+
const recordUidValue = locator.recordUid.trim();
|
|
44344
|
+
const chatSessionUid = locator.chatSessionUid.trim();
|
|
44345
|
+
if (locator.viewerUserId !== expectedViewerUserId || sourceRef === "" || sourceOwnerRef === "" || recordUidValue === "" || !Number.isSafeInteger(locator.recordOwnerUserId) || locator.recordOwnerUserId <= 0 || locator.contextType !== "record" && locator.contextType !== "chat" || locator.contextType === "chat" && chatSessionUid === "") throw new ArkmePluginError("related-quick-note-source-invalid", "当前快记来源无效,请刷新后重试", false, 400);
|
|
43290
44346
|
return {
|
|
43291
|
-
|
|
43292
|
-
|
|
44347
|
+
...locator,
|
|
44348
|
+
sourceRef,
|
|
44349
|
+
sourceOwnerRef,
|
|
44350
|
+
recordUid: recordUidValue,
|
|
44351
|
+
chatSessionUid: locator.contextType === "chat" ? chatSessionUid : ""
|
|
43293
44352
|
};
|
|
43294
44353
|
}
|
|
43295
|
-
|
|
43296
|
-
const
|
|
43297
|
-
|
|
43298
|
-
|
|
43299
|
-
|
|
43300
|
-
|
|
43301
|
-
|
|
43302
|
-
|
|
43303
|
-
|
|
43304
|
-
}
|
|
43305
|
-
async sendPending(session, pending) {
|
|
43306
|
-
try {
|
|
43307
|
-
const data = await this.runtime.authenticatedPost("/api/v1/records/create", {
|
|
43308
|
-
record_uid: pending.recordUid,
|
|
43309
|
-
template_kind: 1,
|
|
43310
|
-
title: "",
|
|
43311
|
-
text_content: pending.textContent,
|
|
43312
|
-
send_at: pending.sendAtMillis
|
|
43313
|
-
}, session);
|
|
43314
|
-
const result = {
|
|
43315
|
-
recordUid: stringValue$1(data.record_uid) || pending.recordUid,
|
|
43316
|
-
status: numberValue$6(data.status)
|
|
43317
|
-
};
|
|
43318
|
-
await this.runtime.stateStore.markSynced(session.userId, pending.recordUid, result.status);
|
|
43319
|
-
return result;
|
|
43320
|
-
} catch (error) {
|
|
43321
|
-
await this.runtime.stateStore.markAttempt(session.userId, pending.recordUid, safeFailureMessage$2(error));
|
|
43322
|
-
throw error;
|
|
44354
|
+
descriptorsFromItems(rawItems, excluded, lockedRecordUids) {
|
|
44355
|
+
const seen = /* @__PURE__ */ new Set();
|
|
44356
|
+
const result = [];
|
|
44357
|
+
for (const raw of rawItems) {
|
|
44358
|
+
if (result.length >= RELATED_QUICK_NOTE_LIMIT || arkmePrivacyLockedRecord(raw)) continue;
|
|
44359
|
+
const descriptor = descriptorFromRaw(raw);
|
|
44360
|
+
if (descriptor === void 0 || excluded.has(descriptor.recordUid) || lockedRecordUids.has(descriptor.recordUid) || seen.has(descriptor.recordUid)) continue;
|
|
44361
|
+
seen.add(descriptor.recordUid);
|
|
44362
|
+
result.push(descriptor);
|
|
43323
44363
|
}
|
|
44364
|
+
return result;
|
|
43324
44365
|
}
|
|
43325
|
-
|
|
43326
|
-
const
|
|
43327
|
-
|
|
43328
|
-
|
|
43329
|
-
|
|
43330
|
-
|
|
43331
|
-
|
|
43332
|
-
|
|
43333
|
-
|
|
43334
|
-
|
|
43335
|
-
|
|
43336
|
-
|
|
43337
|
-
|
|
43338
|
-
|
|
43339
|
-
|
|
43340
|
-
|
|
43341
|
-
|
|
43342
|
-
|
|
43343
|
-
|
|
43344
|
-
|
|
43345
|
-
|
|
43346
|
-
const item = objectValue$1(raw);
|
|
43347
|
-
const core = objectValue$1(item.record_core);
|
|
43348
|
-
return {
|
|
43349
|
-
itemUid: stringValue$1(item.record_uid ?? core.record_uid).trim(),
|
|
43350
|
-
senderName: stringValue$1(item.nickname).trim() || "我",
|
|
43351
|
-
isMe: options.isMe ?? numberValue$6(item.creator_user_id ?? item.owner_user_id ?? core.creator_user_id ?? core.owner_user_id) === userId,
|
|
43352
|
-
sendAtMillis: numberValue$6(item.send_at ?? core.send_at),
|
|
43353
|
-
title: stringValue$1(item.title ?? core.title),
|
|
43354
|
-
textContent: stringValue$1(item.text_content ?? core.text_content),
|
|
43355
|
-
status: numberValue$6(item.status ?? core.status),
|
|
43356
|
-
templateKind: numberValue$6(item.template_kind ?? core.template_kind),
|
|
43357
|
-
displayKind: numberValue$6(item.display_kind ?? core.display_kind),
|
|
43358
|
-
version: numberValue$6(item.version ?? core.version),
|
|
43359
|
-
updateAtMillis: numberValue$6(item.update_at ?? core.update_at),
|
|
43360
|
-
recordDurationMillis: numberValue$6(item.record_duration_millis ?? core.record_duration_millis),
|
|
43361
|
-
editDurationMillis: numberValue$6(item.edit_duration_millis ?? core.edit_duration_millis),
|
|
43362
|
-
contentBlocks: this.media.richContentBlocks(raw, userId, options.displayItems),
|
|
43363
|
-
...options.selfTopic === void 0 ? {} : { selfTopic: options.selfTopic },
|
|
43364
|
-
...options.mediaUnavailable === true ? { mediaUnavailable: true } : {}
|
|
43365
|
-
};
|
|
43366
|
-
}
|
|
43367
|
-
recordItem(raw, userId, options = {}) {
|
|
43368
|
-
const item = objectValue$1(raw);
|
|
43369
|
-
const core = objectValue$1(item.record_core);
|
|
43370
|
-
const recordUid = stringValue$1(item.record_uid ?? core.record_uid).trim();
|
|
43371
|
-
if (recordUid === "") return void 0;
|
|
43372
|
-
return {
|
|
43373
|
-
recordUid,
|
|
43374
|
-
sendAtMillis: numberValue$6(item.send_at ?? core.send_at),
|
|
43375
|
-
title: stringValue$1(core.title),
|
|
43376
|
-
textContent: stringValue$1(core.text_content),
|
|
43377
|
-
templateKind: numberValue$6(core.template_kind),
|
|
43378
|
-
status: numberValue$6(core.status),
|
|
43379
|
-
version: numberValue$6(core.version),
|
|
43380
|
-
creationSource: recordCreationSource(raw),
|
|
43381
|
-
displayKind: numberValue$6(item.display_kind ?? core.display_kind),
|
|
43382
|
-
...userId === void 0 ? {} : { contentBlocks: this.media.richContentBlocks(raw, userId, options.displayItems) },
|
|
43383
|
-
...options.mediaUnavailable === true ? { mediaUnavailable: true } : {}
|
|
43384
|
-
};
|
|
43385
|
-
}
|
|
43386
|
-
isDSHAgentInput(raw) {
|
|
43387
|
-
return isDSHAgentInputRecord(raw);
|
|
44366
|
+
relatedCandidates(response, directItems, excluded, lockedRecordUids) {
|
|
44367
|
+
const rawItems = [...directItems, ...listValue$7(response.similarLs ?? response.similar_ls ?? response.similarRecords ?? response.similar_records)];
|
|
44368
|
+
const blocked = new Set(lockedRecordUids);
|
|
44369
|
+
for (const raw of rawItems) {
|
|
44370
|
+
if (!arkmePrivacyLockedRecord(raw)) continue;
|
|
44371
|
+
const uid = typeof raw === "string" ? raw.trim() : recordUid(raw);
|
|
44372
|
+
if (uid !== "") blocked.add(uid);
|
|
44373
|
+
}
|
|
44374
|
+
const result = [];
|
|
44375
|
+
const seen = /* @__PURE__ */ new Set();
|
|
44376
|
+
for (const raw of rawItems) {
|
|
44377
|
+
const uid = typeof raw === "string" ? raw.trim() : recordUid(raw);
|
|
44378
|
+
if (uid === "" || excluded.has(uid) || blocked.has(uid) || seen.has(uid) || arkmePrivacyLockedRecord(raw)) continue;
|
|
44379
|
+
seen.add(uid);
|
|
44380
|
+
result.push({
|
|
44381
|
+
uid,
|
|
44382
|
+
raw
|
|
44383
|
+
});
|
|
44384
|
+
if (result.length >= RELATED_QUICK_NOTE_LIMIT) break;
|
|
44385
|
+
}
|
|
44386
|
+
return result;
|
|
43388
44387
|
}
|
|
43389
|
-
|
|
43390
|
-
|
|
44388
|
+
async sealReference(reference) {
|
|
44389
|
+
const now = Date.now();
|
|
44390
|
+
for (const [key, value] of this.references) if (value.expiresAtMillis <= now) this.references.delete(key);
|
|
44391
|
+
while (this.references.size >= RELATED_QUICK_NOTE_REF_CAP) {
|
|
44392
|
+
const oldest = this.references.keys().next().value;
|
|
44393
|
+
if (oldest === void 0) break;
|
|
44394
|
+
this.references.delete(oldest);
|
|
44395
|
+
}
|
|
44396
|
+
const nonce = randomUUID();
|
|
44397
|
+
const signature = createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(nonce).digest("base64url");
|
|
44398
|
+
this.references.set(nonce, {
|
|
44399
|
+
...reference,
|
|
44400
|
+
expiresAtMillis: now + RELATED_QUICK_NOTE_REF_TTL_MS
|
|
44401
|
+
});
|
|
44402
|
+
return `arkme-related-quick-note-v1.${nonce}.${signature}`;
|
|
43391
44403
|
}
|
|
43392
|
-
async
|
|
43393
|
-
const
|
|
43394
|
-
|
|
43395
|
-
|
|
43396
|
-
|
|
43397
|
-
|
|
43398
|
-
|
|
43399
|
-
|
|
43400
|
-
|
|
43401
|
-
|
|
44404
|
+
async openReference(relatedRef, expectedViewerUserId, expectedSourceRef) {
|
|
44405
|
+
const parts = relatedRef.trim().split(".");
|
|
44406
|
+
if (parts.length !== 3 || parts[0] !== "arkme-related-quick-note-v1") throw this.invalidReference();
|
|
44407
|
+
const nonce = parts[1] ?? "";
|
|
44408
|
+
const supplied = Buffer.from(parts[2] ?? "", "base64url");
|
|
44409
|
+
const expected = createHmac("sha256", await this.runtime.stateStore.uniqueCode()).update(nonce).digest();
|
|
44410
|
+
if (nonce === "" || supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) throw this.invalidReference();
|
|
44411
|
+
const reference = this.references.get(nonce);
|
|
44412
|
+
if (reference === void 0 || reference.expiresAtMillis <= Date.now()) {
|
|
44413
|
+
this.references.delete(nonce);
|
|
44414
|
+
throw new ArkmePluginError("related-quick-note-ref-expired", "相关快记引用已过期,请刷新后重试", true, 410);
|
|
43402
44415
|
}
|
|
43403
|
-
|
|
43404
|
-
|
|
43405
|
-
|
|
43406
|
-
|
|
44416
|
+
if (reference.viewerUserId !== expectedViewerUserId || reference.sourceRef !== expectedSourceRef) throw this.invalidReference();
|
|
44417
|
+
return reference;
|
|
44418
|
+
}
|
|
44419
|
+
invalidReference() {
|
|
44420
|
+
return new ArkmePluginError("related-quick-note-ref-invalid", "相关快记引用无效,请刷新后重试", false, 403);
|
|
43407
44421
|
}
|
|
43408
44422
|
};
|
|
43409
44423
|
//#endregion
|
|
@@ -46707,6 +47721,31 @@ function integerValue(value) {
|
|
|
46707
47721
|
function listValue(value) {
|
|
46708
47722
|
return Array.isArray(value) ? value : [];
|
|
46709
47723
|
}
|
|
47724
|
+
function extensionShareRefFromUrl(rawUrl) {
|
|
47725
|
+
try {
|
|
47726
|
+
return new URL(rawUrl).pathname.split("/").at(-1) ?? "";
|
|
47727
|
+
} catch {
|
|
47728
|
+
return "";
|
|
47729
|
+
}
|
|
47730
|
+
}
|
|
47731
|
+
function worldExtensionPublicationShare(rawPublication, rawItem) {
|
|
47732
|
+
const share = objectValue$1(rawPublication.share ?? rawItem.share);
|
|
47733
|
+
const url = stringValue$1(share.url ?? rawPublication.share_url ?? rawItem.share_url).trim();
|
|
47734
|
+
if (url === "" || url.length > 4096) return void 0;
|
|
47735
|
+
const ref = stringValue$1(share.ref ?? rawPublication.share_ref ?? rawItem.share_ref).trim() || extensionShareRefFromUrl(url);
|
|
47736
|
+
if (!/^extshare_[0-9a-f]{32}$/.test(ref)) return void 0;
|
|
47737
|
+
let parsed;
|
|
47738
|
+
try {
|
|
47739
|
+
parsed = new URL(url);
|
|
47740
|
+
} catch {
|
|
47741
|
+
return;
|
|
47742
|
+
}
|
|
47743
|
+
if (parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "" || !parsed.pathname.endsWith(`/${ref}`)) return;
|
|
47744
|
+
return {
|
|
47745
|
+
ref,
|
|
47746
|
+
url: parsed.href
|
|
47747
|
+
};
|
|
47748
|
+
}
|
|
46710
47749
|
function isTopLevelWorldRecord(raw) {
|
|
46711
47750
|
return stringValue$1(objectValue$1(raw).parent_record_uid).trim() === "";
|
|
46712
47751
|
}
|
|
@@ -47553,6 +48592,10 @@ var WorldService = class {
|
|
|
47553
48592
|
version: stringValue$1(rawExtensionPublication.version).trim(),
|
|
47554
48593
|
name: stringValue$1(rawExtensionPublication.name).trim() || "未命名插件",
|
|
47555
48594
|
description: stringValue$1(rawExtensionPublication.description).trim(),
|
|
48595
|
+
...(() => {
|
|
48596
|
+
const share = worldExtensionPublicationShare(rawExtensionPublication, item);
|
|
48597
|
+
return share === void 0 ? {} : { share };
|
|
48598
|
+
})(),
|
|
47556
48599
|
...(() => {
|
|
47557
48600
|
const iconRef = stringValue$1(rawExtensionPublication.icon_ref).trim();
|
|
47558
48601
|
return iconRef === "" ? {} : { iconRef };
|
|
@@ -47834,6 +48877,7 @@ var ArkmeService = class {
|
|
|
47834
48877
|
linkMetadata;
|
|
47835
48878
|
aiPolish;
|
|
47836
48879
|
chat;
|
|
48880
|
+
relatedQuickNote;
|
|
47837
48881
|
contact;
|
|
47838
48882
|
contactDirectory;
|
|
47839
48883
|
unmarkedSpeaker;
|
|
@@ -47886,6 +48930,7 @@ var ArkmeService = class {
|
|
|
47886
48930
|
this.botConversation = new BotConversationService(this.runtime, this.bot, this.chat, async () => {
|
|
47887
48931
|
await this.realtime.invalidateRecordProjection();
|
|
47888
48932
|
});
|
|
48933
|
+
this.relatedQuickNote = new RelatedQuickNoteService(this.runtime, this.record, this.media, this.profile, this.privacy);
|
|
47889
48934
|
this.contactDirectory = new ContactDirectoryService(this.runtime, this.source, this.bot, this.profile, this.world, this.chat);
|
|
47890
48935
|
this.unmarkedSpeaker = new UnmarkedSpeakerService(this.runtime, this.media);
|
|
47891
48936
|
this.contact = new ContactService(this.runtime, this.source, this.profile, this.realtime);
|
|
@@ -47971,6 +49016,7 @@ var ArkmeService = class {
|
|
|
47971
49016
|
this.media.dispose();
|
|
47972
49017
|
this.aiPolish.dispose();
|
|
47973
49018
|
this.interwoven.dispose();
|
|
49019
|
+
this.relatedQuickNote.dispose();
|
|
47974
49020
|
this.world.dispose();
|
|
47975
49021
|
this.arrangement.dispose();
|
|
47976
49022
|
this.contact.dispose();
|
|
@@ -48132,6 +49178,7 @@ var ArkmeService = class {
|
|
|
48132
49178
|
forwardContent: true,
|
|
48133
49179
|
sourceTextSend: true,
|
|
48134
49180
|
messageReadReceipts: true,
|
|
49181
|
+
messageReport: true,
|
|
48135
49182
|
richContentRead: this.config.richMediaRenderEnabled !== false,
|
|
48136
49183
|
richContentSend: this.config.richMediaSendEnabled !== false,
|
|
48137
49184
|
fileUpload: this.config.richMediaSendEnabled !== false,
|
|
@@ -48230,6 +49277,7 @@ var ArkmeService = class {
|
|
|
48230
49277
|
this.runtime.dispose();
|
|
48231
49278
|
this.outgoingCall.dispose();
|
|
48232
49279
|
this.interwoven.dispose();
|
|
49280
|
+
this.relatedQuickNote.dispose();
|
|
48233
49281
|
this.world.dispose();
|
|
48234
49282
|
this.linkMetadata.dispose();
|
|
48235
49283
|
}
|
|
@@ -48398,6 +49446,15 @@ var ArkmeService = class {
|
|
|
48398
49446
|
async interwovenMomentDetail(sourceRef, momentRef, signal) {
|
|
48399
49447
|
return await this.interwoven.interwovenMomentDetail(sourceRef, momentRef, signal);
|
|
48400
49448
|
}
|
|
49449
|
+
async relatedQuickNotesFromMessage(sourceRef, messageActionRef, signal) {
|
|
49450
|
+
return await this.relatedQuickNote.list(await this.chat.relatedQuickNoteLocator(sourceRef, messageActionRef), signal);
|
|
49451
|
+
}
|
|
49452
|
+
async relatedQuickNotesFromMoment(sourceRef, momentRef, signal) {
|
|
49453
|
+
return await this.relatedQuickNote.list(await this.interwoven.relatedQuickNoteLocator(sourceRef, momentRef, signal), signal);
|
|
49454
|
+
}
|
|
49455
|
+
async relatedQuickNoteDetail(sourceRef, relatedRef, signal) {
|
|
49456
|
+
return await this.relatedQuickNote.detail(sourceRef, relatedRef, signal);
|
|
49457
|
+
}
|
|
48401
49458
|
async joinDSHBetaCommunity(signal) {
|
|
48402
49459
|
return await this.community.joinDSHBetaCommunity(signal);
|
|
48403
49460
|
}
|
|
@@ -48519,6 +49576,12 @@ var ArkmeService = class {
|
|
|
48519
49576
|
async sharedRecordingDetail(detailRef, options = {}) {
|
|
48520
49577
|
return await this.chat.sharedRecordingDetail(detailRef, options);
|
|
48521
49578
|
}
|
|
49579
|
+
async messageSnapshotDetail(sourceRef, actionRef, options = {}) {
|
|
49580
|
+
return await this.chat.messageSnapshotDetail(sourceRef, actionRef, options);
|
|
49581
|
+
}
|
|
49582
|
+
async saveMessageLocation(sourceRef, itemUid, location, recordVersion, options = {}) {
|
|
49583
|
+
await this.chat.saveMessageLocation(sourceRef, itemUid, location, recordVersion, options);
|
|
49584
|
+
}
|
|
48522
49585
|
async messageReadReceiptSummaries(sourceRef, items, options = {}) {
|
|
48523
49586
|
return await this.chat.messageReadReceiptSummaries(sourceRef, items, options);
|
|
48524
49587
|
}
|
|
@@ -48841,25 +49904,27 @@ var ArkmeService = class {
|
|
|
48841
49904
|
return await this.world.publishWorldFileAssets(input);
|
|
48842
49905
|
}
|
|
48843
49906
|
async createText(recordUid, textContent) {
|
|
48844
|
-
|
|
49907
|
+
const result = await this.record.createText(recordUid, textContent);
|
|
49908
|
+
await this.realtime.invalidateRecordProjection();
|
|
49909
|
+
return result;
|
|
48845
49910
|
}
|
|
48846
49911
|
async createTextForConversation(recordUid, textContent) {
|
|
48847
|
-
|
|
49912
|
+
const result = await this.record.createTextForConversation(recordUid, textContent);
|
|
49913
|
+
if (result.localState !== "failed") await this.realtime.invalidateRecordProjection();
|
|
49914
|
+
return result;
|
|
48848
49915
|
}
|
|
48849
49916
|
async createDSHAgentInputText(recordUid, textContent, sendAtMillis) {
|
|
48850
49917
|
const result = await this.record.createDSHAgentInputText(recordUid, textContent, sendAtMillis);
|
|
48851
|
-
this.realtime.
|
|
48852
|
-
type: "projection-invalidated",
|
|
48853
|
-
revision: this.realtime.nextChatClientRevision(),
|
|
48854
|
-
projection: "record"
|
|
48855
|
-
});
|
|
49918
|
+
await this.realtime.invalidateRecordProjection();
|
|
48856
49919
|
return result;
|
|
48857
49920
|
}
|
|
48858
49921
|
async pendingWrites() {
|
|
48859
49922
|
return await this.record.pendingWrites();
|
|
48860
49923
|
}
|
|
48861
49924
|
async retryPending(recordUid) {
|
|
48862
|
-
|
|
49925
|
+
const result = await this.record.retryPending(recordUid);
|
|
49926
|
+
await this.realtime.invalidateRecordProjection();
|
|
49927
|
+
return result;
|
|
48863
49928
|
}
|
|
48864
49929
|
recordUid(raw) {
|
|
48865
49930
|
return this.record.recordUid(raw);
|