@senguoyun/dsh-arkme 0.1.13 → 0.1.14
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/docs/consumer-plugin-contract.md +3 -1
- package/docs/extension-market-controls.md +46 -7
- package/docs/gui-production-integration.md +10 -9
- package/lib/client.js +43662 -46867
- package/lib/client.js.map +1 -1
- package/lib/index.js +455 -315
- package/lib/persistent-extension.js +1 -1
- package/lib/{persistent-runtime-Cki0XC3L.js → persistent-runtime-BAArZI-P.js} +467 -96
- package/lib/sdk.js +51 -15
- package/lib/types/arkme-service.d.ts +14 -9
- package/lib/types/arkme-service.d.ts.map +1 -1
- package/lib/types/bot-avatar-ref.d.ts +3 -0
- package/lib/types/bot-avatar-ref.d.ts.map +1 -0
- package/lib/types/client/ArkmeBotCreateDialog.d.ts +6 -0
- package/lib/types/client/ArkmeBotCreateDialog.d.ts.map +1 -0
- package/lib/types/client/ArkmeCalendarSurface.d.ts +4 -1
- package/lib/types/client/ArkmeCalendarSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeConversationSurface.d.ts +8 -18
- package/lib/types/client/ArkmeConversationSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeExtensionPublishDialog.d.ts.map +1 -1
- package/lib/types/client/ArkmeFooterDropdown.d.ts.map +1 -1
- package/lib/types/client/ArkmeLogin.d.ts.map +1 -1
- package/lib/types/client/ArkmeMarketplace.d.ts +14 -3
- package/lib/types/client/ArkmeMarketplace.d.ts.map +1 -1
- package/lib/types/client/ArkmePersistentShell.d.ts +20 -0
- package/lib/types/client/ArkmePersistentShell.d.ts.map +1 -0
- package/lib/types/client/ArkmeProductNavigation.d.ts +4 -3
- package/lib/types/client/ArkmeProductNavigation.d.ts.map +1 -1
- package/lib/types/client/ArkmeQuickAdd.d.ts.map +1 -1
- package/lib/types/client/ArkmeRecordingSurface.d.ts +3 -109
- package/lib/types/client/ArkmeRecordingSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeSettingsRow.d.ts +1 -1
- package/lib/types/client/ArkmeSettingsRow.d.ts.map +1 -1
- package/lib/types/client/ArkmeSettingsSurface.d.ts +4 -1
- package/lib/types/client/ArkmeSettingsSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeSidebar.d.ts +7 -1
- package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
- package/lib/types/client/ArkmeStartupAuthGate.d.ts.map +1 -1
- package/lib/types/client/ArkmeVirtualWorkspace.d.ts +8 -9
- package/lib/types/client/ArkmeVirtualWorkspace.d.ts.map +1 -1
- package/lib/types/client/ArkmeWorldSurface.d.ts +63 -4
- package/lib/types/client/ArkmeWorldSurface.d.ts.map +1 -1
- package/lib/types/client/DeepSeekHarnessSurface.d.ts +6 -0
- package/lib/types/client/DeepSeekHarnessSurface.d.ts.map +1 -0
- package/lib/types/client/api.d.ts +1 -1
- package/lib/types/client/api.d.ts.map +1 -1
- package/lib/types/client/arkme-emoji.d.ts +3 -0
- package/lib/types/client/arkme-emoji.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +6 -4
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/redesign/ArkmeRootFrame.d.ts +19 -0
- package/lib/types/client/redesign/ArkmeRootFrame.d.ts.map +1 -0
- package/lib/types/client/redesign/ArkmeTaskSurface.d.ts +15 -0
- package/lib/types/client/redesign/ArkmeTaskSurface.d.ts.map +1 -0
- package/lib/types/client/redesign/ArkmeWorkspaceDialog.d.ts +9 -0
- package/lib/types/client/redesign/ArkmeWorkspaceDialog.d.ts.map +1 -0
- package/lib/types/client/redesign/layout-controller.d.ts +17 -0
- package/lib/types/client/redesign/layout-controller.d.ts.map +1 -0
- package/lib/types/client/redesign/styles.d.ts +3 -0
- package/lib/types/client/redesign/styles.d.ts.map +1 -0
- package/lib/types/client/redesign/task-session.d.ts +14 -0
- package/lib/types/client/redesign/task-session.d.ts.map +1 -0
- package/lib/types/client/redesign/theme-presenter.d.ts +10 -0
- package/lib/types/client/redesign/theme-presenter.d.ts.map +1 -0
- package/lib/types/client/slots-contract.d.ts +2 -2
- package/lib/types/client/slots-contract.d.ts.map +1 -1
- package/lib/types/client/ui-controller.d.ts +19 -9
- package/lib/types/client/ui-controller.d.ts.map +1 -1
- package/lib/types/client/world-voiceprint-expectation-copy.d.ts +7 -0
- package/lib/types/client/world-voiceprint-expectation-copy.d.ts.map +1 -0
- package/lib/types/extensions/manager.d.ts +3 -0
- package/lib/types/extensions/manager.d.ts.map +1 -1
- package/lib/types/extensions/owned-inventory.d.ts +27 -1
- package/lib/types/extensions/owned-inventory.d.ts.map +1 -1
- package/lib/types/extensions/owned-refs.d.ts +1 -0
- package/lib/types/extensions/owned-refs.d.ts.map +1 -1
- package/lib/types/extensions/owned-store.d.ts +8 -0
- package/lib/types/extensions/owned-store.d.ts.map +1 -1
- package/lib/types/extensions/publisher-role.d.ts +9 -0
- package/lib/types/extensions/publisher-role.d.ts.map +1 -0
- package/lib/types/extensions/types.d.ts +11 -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 +2 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/outgoing-call-assets.d.ts.map +1 -1
- package/lib/types/recording-presentation.d.ts +2 -2
- package/lib/types/recording-presentation.d.ts.map +1 -1
- package/lib/types/sdk/index.d.ts +22 -8
- package/lib/types/sdk/index.d.ts.map +1 -1
- package/lib/types/services/bot-service.d.ts.map +1 -1
- package/lib/types/services/record-service.d.ts +2 -1
- package/lib/types/services/record-service.d.ts.map +1 -1
- package/lib/types/services/recording-service.d.ts +2 -4
- package/lib/types/services/recording-service.d.ts.map +1 -1
- package/lib/types/services/world-service.d.ts +40 -6
- package/lib/types/services/world-service.d.ts.map +1 -1
- package/lib/types/tools/business/bots/create.d.ts.map +1 -1
- package/lib/types/tools/business/index.d.ts.map +1 -1
- package/lib/types/tools/business/recordings/index.d.ts +1 -2
- package/lib/types/tools/business/recordings/index.d.ts.map +1 -1
- package/lib/types/tools/business/world/index.d.ts +2 -0
- package/lib/types/tools/business/world/index.d.ts.map +1 -1
- package/lib/types/tools/business/world/user.d.ts +2 -0
- package/lib/types/tools/business/world/user.d.ts.map +1 -0
- package/lib/types/tools/business/world/voiceprint-social-context.d.ts +2 -0
- package/lib/types/tools/business/world/voiceprint-social-context.d.ts.map +1 -0
- package/lib/types/tools/extensions/index.d.ts.map +1 -1
- package/lib/types/tools/ports/recordings.d.ts +2 -3
- package/lib/types/tools/ports/recordings.d.ts.map +1 -1
- package/lib/types/tools/ports/world.d.ts +10 -1
- package/lib/types/tools/ports/world.d.ts.map +1 -1
- package/lib/types/tools/prompts/business.d.ts.map +1 -1
- package/lib/types/types.d.ts +39 -16
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +7 -4
- package/assets/desktop_call/avatar-lin-xiaoman.jpeg +0 -0
- package/assets/desktop_call/avatar-mother.jpg +0 -0
- package/assets/desktop_call/avatar-self.png +0 -0
- package/assets/desktop_call/call-add-linear.svg +0 -13
- package/assets/desktop_call/icon-scan-add-contact.svg +0 -4
- package/assets/desktop_call/profile-circle-linear.svg +0 -11
- package/assets/desktop_call/user-add-linear.svg +0 -15
- package/lib/types/client/ArkmeCallHistorySurface.d.ts +0 -57
- package/lib/types/client/ArkmeCallHistorySurface.d.ts.map +0 -1
- package/lib/types/client/demo-audio.d.ts +0 -2
- package/lib/types/client/demo-audio.d.ts.map +0 -1
- package/lib/types/client/personal-test-edition.d.ts +0 -17
- package/lib/types/client/personal-test-edition.d.ts.map +0 -1
|
@@ -2454,6 +2454,13 @@ var AuthService = class {
|
|
|
2454
2454
|
}
|
|
2455
2455
|
};
|
|
2456
2456
|
//#endregion
|
|
2457
|
+
//#region src/bot-avatar-ref.ts
|
|
2458
|
+
const ARKME_BOT_AVATAR_REF_PATTERN = /^file_asset:\/\/[A-Za-z0-9_-]{8,128}$/;
|
|
2459
|
+
/** Bot avatars cross process boundaries only as account-scoped file asset references. */
|
|
2460
|
+
function isArkmeBotAvatarRef(value) {
|
|
2461
|
+
return ARKME_BOT_AVATAR_REF_PATTERN.test(value.trim());
|
|
2462
|
+
}
|
|
2463
|
+
//#endregion
|
|
2457
2464
|
//#region src/secret-value.ts
|
|
2458
2465
|
var SecretValue = class {
|
|
2459
2466
|
#value;
|
|
@@ -2528,6 +2535,7 @@ var BotService = class {
|
|
|
2528
2535
|
const avatar = input.avatar?.trim() ?? "";
|
|
2529
2536
|
if (name === "") throw new ArkmePluginError("bot-name-invalid", "Bot 名称不能为空", false);
|
|
2530
2537
|
if (provider !== "openclaw" && provider !== "webhook") throw new ArkmePluginError("bot-provider-unsupported", "Bot Provider 不受支持", false, 400);
|
|
2538
|
+
if (avatar !== "" && !isArkmeBotAvatarRef(avatar)) throw new ArkmePluginError("bot-avatar-invalid", "Bot 头像引用无效", false, 400);
|
|
2531
2539
|
const session = await this.runtime.requireSession();
|
|
2532
2540
|
let data;
|
|
2533
2541
|
try {
|
|
@@ -7389,6 +7397,43 @@ var RecordService = class {
|
|
|
7389
7397
|
};
|
|
7390
7398
|
}
|
|
7391
7399
|
}
|
|
7400
|
+
async createFileAssetsForConversation(recordUid, textContent, assets) {
|
|
7401
|
+
const session = await this.runtime.requireSession();
|
|
7402
|
+
const normalizedUid = recordUid.trim();
|
|
7403
|
+
const normalizedText = textContent.trim();
|
|
7404
|
+
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);
|
|
7405
|
+
if (assets.length === 0 || assets.length > 20 || normalizedText.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("record-file-assets-invalid", "附件内容为空、过长或数量超限", false);
|
|
7406
|
+
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 || ![
|
|
7407
|
+
1,
|
|
7408
|
+
2,
|
|
7409
|
+
3,
|
|
7410
|
+
4
|
|
7411
|
+
].includes(asset.fileKind)) throw new ArkmePluginError("record-file-asset-invalid", "附件资产参数无效", false);
|
|
7412
|
+
const data = await this.runtime.authenticatedPost("/api/v1/records/create", {
|
|
7413
|
+
record_uid: normalizedUid,
|
|
7414
|
+
template_kind: 2,
|
|
7415
|
+
display_kind: 0,
|
|
7416
|
+
title: "",
|
|
7417
|
+
text_content: normalizedText,
|
|
7418
|
+
content_payload: {
|
|
7419
|
+
payload_kind: 2,
|
|
7420
|
+
schema_version: 1,
|
|
7421
|
+
text_state: normalizedText === "" ? 3 : 1,
|
|
7422
|
+
media_refs: assets.map((asset, index) => ({
|
|
7423
|
+
file_asset_uid: asset.fileAssetUid,
|
|
7424
|
+
content_file_role: 1,
|
|
7425
|
+
render_role: 1,
|
|
7426
|
+
sort_order: index,
|
|
7427
|
+
file_name: asset.fileName
|
|
7428
|
+
}))
|
|
7429
|
+
},
|
|
7430
|
+
send_at: Date.now()
|
|
7431
|
+
}, session);
|
|
7432
|
+
return {
|
|
7433
|
+
recordUid: stringValue$1(data.record_uid).trim() || normalizedUid,
|
|
7434
|
+
status: numberValue$7(data.status)
|
|
7435
|
+
};
|
|
7436
|
+
}
|
|
7392
7437
|
async pendingWrites() {
|
|
7393
7438
|
const session = await this.runtime.requireSession();
|
|
7394
7439
|
return await this.runtime.stateStore.listPending(session.userId);
|
|
@@ -7532,7 +7577,7 @@ function displayTimestamp(value) {
|
|
|
7532
7577
|
const parsed = Date.parse(stringValue(value));
|
|
7533
7578
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
7534
7579
|
}
|
|
7535
|
-
function projectRecordingTranscripts(response, speakerResponse
|
|
7580
|
+
function projectRecordingTranscripts(response, speakerResponse) {
|
|
7536
7581
|
const data = objectValue(response);
|
|
7537
7582
|
const sessions = /* @__PURE__ */ new Map();
|
|
7538
7583
|
const sessionSpeakerColorIndexes = /* @__PURE__ */ new Map();
|
|
@@ -7576,32 +7621,7 @@ function projectRecordingTranscripts(response, speakerResponse, source = "system
|
|
|
7576
7621
|
const sessionSpeakers = listValue$6(session.spk_ls ?? session.speakers).map(objectValue);
|
|
7577
7622
|
const childOffset = numberValue$6(child.start_at);
|
|
7578
7623
|
const childStart = childOffset >= 1e11 ? childOffset : numberValue$6(session.start_at) + childOffset;
|
|
7579
|
-
const rows = listValue$6(
|
|
7580
|
-
const doubaoStatus = numberValue$6(child.doubao_asr_status);
|
|
7581
|
-
if (source === "doubao" && (doubaoStatus === 1 || doubaoStatus === 2 || doubaoStatus === 4 || doubaoStatus === 5)) {
|
|
7582
|
-
const transcriptStatus = doubaoStatus === 1 || doubaoStatus === 2 ? "processing" : doubaoStatus === 4 ? "silent" : "failed";
|
|
7583
|
-
const text = transcriptStatus === "processing" ? "豆包转写中..." : transcriptStatus === "silent" ? "豆包未识别到人声" : "豆包转写失败";
|
|
7584
|
-
const label = transcriptStatus === "processing" ? "豆包转写中" : transcriptStatus === "silent" ? "豆包静音" : "豆包失败";
|
|
7585
|
-
projected.push({
|
|
7586
|
-
itemId: `${childId || sessionId}:doubao:status`,
|
|
7587
|
-
sessionId,
|
|
7588
|
-
childId,
|
|
7589
|
-
asrItemIndex: 0,
|
|
7590
|
-
transcriptSource: "doubao",
|
|
7591
|
-
startAtMillis: childStart,
|
|
7592
|
-
endAtMillis: childStart + Math.max(0, numberValue$6(child.duration)),
|
|
7593
|
-
speakerNumber: -1,
|
|
7594
|
-
speakerColorIndex: -1,
|
|
7595
|
-
speakerLabel: label,
|
|
7596
|
-
isSelf: false,
|
|
7597
|
-
isBackground: false,
|
|
7598
|
-
text,
|
|
7599
|
-
transcriptStatus,
|
|
7600
|
-
sourceIndex
|
|
7601
|
-
});
|
|
7602
|
-
sourceIndex += 1;
|
|
7603
|
-
continue;
|
|
7604
|
-
}
|
|
7624
|
+
const rows = listValue$6(child.asr);
|
|
7605
7625
|
for (let index = 0; index < rows.length; index += 1) {
|
|
7606
7626
|
const row = objectValue(rows[index]);
|
|
7607
7627
|
const isBackground = numberValue$6(row.b ?? row.background) === 1 || row.background === true;
|
|
@@ -7615,15 +7635,15 @@ function projectRecordingTranscripts(response, speakerResponse, source = "system
|
|
|
7615
7635
|
const persistentSpeakerNumber = optionalNumberValue(sessionSpeaker.speaker_display_number ?? sessionSpeaker.speakerDisplayNumber);
|
|
7616
7636
|
const speakerNumber = persistentSpeakerNumber !== void 0 && persistentSpeakerNumber > 0 ? persistentSpeakerNumber : rawSpeakerNumber;
|
|
7617
7637
|
const speakerColorIndex = sessionSpeakerColorIndexes.get(`${sessionId}:${rawSpeakerNumber}`) ?? Math.max(0, rawSpeakerNumber);
|
|
7618
|
-
const speakerLabel =
|
|
7638
|
+
const speakerLabel = speakerNumber >= 0 ? `说话人 ${speakerNumber}` : "未知说话人";
|
|
7619
7639
|
const startOffset = numberValue$6(row.s ?? row.start_at);
|
|
7620
7640
|
const endOffset = Math.max(startOffset, numberValue$6(row.e ?? row.end_at));
|
|
7621
7641
|
projected.push({
|
|
7622
|
-
itemId:
|
|
7642
|
+
itemId: `${childId || sessionId}:${index}`,
|
|
7623
7643
|
sessionId,
|
|
7624
7644
|
childId,
|
|
7625
7645
|
asrItemIndex: index,
|
|
7626
|
-
transcriptSource:
|
|
7646
|
+
transcriptSource: "system",
|
|
7627
7647
|
startAtMillis: childStart + startOffset,
|
|
7628
7648
|
endAtMillis: childStart + endOffset,
|
|
7629
7649
|
speakerNumber,
|
|
@@ -7632,7 +7652,6 @@ function projectRecordingTranscripts(response, speakerResponse, source = "system
|
|
|
7632
7652
|
isSelf,
|
|
7633
7653
|
isBackground,
|
|
7634
7654
|
text,
|
|
7635
|
-
...source === "doubao" ? { transcriptStatus: "ready" } : {},
|
|
7636
7655
|
sourceIndex
|
|
7637
7656
|
});
|
|
7638
7657
|
sourceIndex += 1;
|
|
@@ -7879,21 +7898,7 @@ var RecordingService = class {
|
|
|
7879
7898
|
days
|
|
7880
7899
|
};
|
|
7881
7900
|
}
|
|
7882
|
-
async recordingTranscript(dateStamp, signal
|
|
7883
|
-
const sections = await this.recordingTranscriptSections(dateStamp, signal);
|
|
7884
|
-
return source === "doubao" ? sections.doubao : sections.system;
|
|
7885
|
-
}
|
|
7886
|
-
async startRecordingDoubaoBackfill(dateStamp, signal) {
|
|
7887
|
-
const date = this.recordingDayStart(dateStamp).getTime();
|
|
7888
|
-
const session = await this.runtime.requireSession();
|
|
7889
|
-
const data = await this.runtime.authenticatedAudioPost("/api/v1/audio/doubao-asr/backfill-day", { start_at: date }, session, signal);
|
|
7890
|
-
return {
|
|
7891
|
-
queuedChildCount: Math.max(0, Math.trunc(numberValue$5(data.queued_child_count))),
|
|
7892
|
-
inFlightChildCount: Math.max(0, Math.trunc(numberValue$5(data.in_flight_child_count))),
|
|
7893
|
-
missingAudioChildCount: Math.max(0, Math.trunc(numberValue$5(data.missing_audio_child_count)))
|
|
7894
|
-
};
|
|
7895
|
-
}
|
|
7896
|
-
async recordingTranscriptSections(dateStamp, signal) {
|
|
7901
|
+
async recordingTranscript(dateStamp, signal) {
|
|
7897
7902
|
const dayStart = this.recordingDayStart(dateStamp);
|
|
7898
7903
|
const date = dayStart.getTime();
|
|
7899
7904
|
const session = await this.runtime.requireSession();
|
|
@@ -7905,29 +7910,14 @@ var RecordingService = class {
|
|
|
7905
7910
|
let totalDurationMillis = 0;
|
|
7906
7911
|
for (const rawSession of listValue$5(transcriptResult.value.session_ls)) totalDurationMillis += Math.max(0, numberValue$5(objectValue$1(rawSession).duration));
|
|
7907
7912
|
const speakerData = speakerResult.status === "fulfilled" ? listValue$5(speakerResult.value.spk_ls) : [];
|
|
7908
|
-
const
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
message: systemItems.length > 0 ? "" : "当天无录音",
|
|
7915
|
-
identityCoverage,
|
|
7913
|
+
const items = projectRecordingTranscripts(transcriptResult.value, speakerData);
|
|
7914
|
+
return {
|
|
7915
|
+
state: items.length > 0 ? "ready" : "empty",
|
|
7916
|
+
items,
|
|
7917
|
+
message: items.length > 0 ? "" : "当天无录音",
|
|
7918
|
+
identityCoverage: speakerResult.status === "fulfilled" ? "complete" : "partial",
|
|
7916
7919
|
totalDurationMillis
|
|
7917
7920
|
};
|
|
7918
|
-
const hasProcessing = doubaoItems.some((item) => item.transcriptStatus === "processing");
|
|
7919
|
-
const hasReady = doubaoItems.some((item) => item.transcriptStatus === "ready" || item.transcriptStatus === "silent" || item.transcriptStatus === void 0);
|
|
7920
|
-
const hasFailed = doubaoItems.some((item) => item.transcriptStatus === "failed");
|
|
7921
|
-
return {
|
|
7922
|
-
system,
|
|
7923
|
-
doubao: {
|
|
7924
|
-
state: hasProcessing ? "processing" : hasReady ? "ready" : hasFailed ? "failed" : "empty",
|
|
7925
|
-
items: doubaoItems,
|
|
7926
|
-
message: hasProcessing ? "豆包转写中" : hasReady ? "" : hasFailed ? "豆包转写失败" : "豆包转写尚未生成",
|
|
7927
|
-
identityCoverage,
|
|
7928
|
-
totalDurationMillis
|
|
7929
|
-
}
|
|
7930
|
-
};
|
|
7931
7921
|
}
|
|
7932
7922
|
async recordingProjection(dateStamp, kind, signal) {
|
|
7933
7923
|
const dayStart = this.recordingDayStart(dateStamp);
|
|
@@ -7965,7 +7955,6 @@ var RecordingService = class {
|
|
|
7965
7955
|
version: 1,
|
|
7966
7956
|
dateStamp: numberValue$5(raw.dateStamp),
|
|
7967
7957
|
content: content === "summary" || content === "timeline" ? content : "transcript",
|
|
7968
|
-
...content === "transcript" && (raw.transcriptSource === "system" || raw.transcriptSource === "doubao") ? { transcriptSource: raw.transcriptSource } : {},
|
|
7969
7958
|
itemOffset: numberValue$5(raw.itemOffset),
|
|
7970
7959
|
textOffset: numberValue$5(raw.textOffset),
|
|
7971
7960
|
fingerprint: stringValue$1(raw.fingerprint),
|
|
@@ -7975,31 +7964,25 @@ var RecordingService = class {
|
|
|
7975
7964
|
"transcript",
|
|
7976
7965
|
"summary",
|
|
7977
7966
|
"timeline"
|
|
7978
|
-
].includes(String(content)) ||
|
|
7967
|
+
].includes(String(content)) || !Number.isSafeInteger(payload.dateStamp) || payload.dateStamp <= 0 || !Number.isSafeInteger(payload.itemOffset) || payload.itemOffset < 0 || !Number.isSafeInteger(payload.textOffset) || payload.textOffset < 0 || payload.fingerprint === "") throw new ArkmePluginError("recording-cursor-invalid", "录音分页游标无效", false);
|
|
7979
7968
|
return payload;
|
|
7980
7969
|
}
|
|
7981
7970
|
async recordingDay(dateStamp) {
|
|
7982
7971
|
const date = this.recordingDayStart(dateStamp).getTime();
|
|
7983
7972
|
const [transcriptResult, summaryResult, timelineResult] = await Promise.allSettled([
|
|
7984
|
-
this.
|
|
7973
|
+
this.recordingTranscript(date),
|
|
7985
7974
|
this.recordingProjection(date, "summary"),
|
|
7986
7975
|
this.recordingProjection(date, "timeline")
|
|
7987
7976
|
]);
|
|
7988
|
-
const transcript = transcriptResult.status === "fulfilled" ? transcriptResult.value
|
|
7989
|
-
state: "error",
|
|
7990
|
-
items: [],
|
|
7991
|
-
message: safeFailureMessage$2(transcriptResult.reason)
|
|
7992
|
-
};
|
|
7993
|
-
const doubaoTranscript = transcriptResult.status === "fulfilled" ? transcriptResult.value.doubao : {
|
|
7977
|
+
const transcript = transcriptResult.status === "fulfilled" ? transcriptResult.value : {
|
|
7994
7978
|
state: "error",
|
|
7995
7979
|
items: [],
|
|
7996
7980
|
message: safeFailureMessage$2(transcriptResult.reason)
|
|
7997
7981
|
};
|
|
7998
7982
|
return {
|
|
7999
7983
|
dateStamp: date,
|
|
8000
|
-
totalDurationMillis: transcriptResult.status === "fulfilled" ? transcriptResult.value.
|
|
7984
|
+
totalDurationMillis: transcriptResult.status === "fulfilled" ? transcriptResult.value.totalDurationMillis : 0,
|
|
8001
7985
|
transcript,
|
|
8002
|
-
doubaoTranscript,
|
|
8003
7986
|
summary: summaryResult.status === "fulfilled" ? summaryResult.value : {
|
|
8004
7987
|
state: "error",
|
|
8005
7988
|
items: [],
|
|
@@ -9427,6 +9410,12 @@ var WechatService = class {
|
|
|
9427
9410
|
}
|
|
9428
9411
|
};
|
|
9429
9412
|
//#endregion
|
|
9413
|
+
//#region src/types.ts
|
|
9414
|
+
const ARKME_PROVIDER_CONTRACT_VERSION = 1;
|
|
9415
|
+
const ARKME_DEFAULT_SHARE_WEBSITE = "https://app.arkme.ai";
|
|
9416
|
+
const ARKME_WORLD_PUBLISH_MAX_IMAGES = 9;
|
|
9417
|
+
const ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
9418
|
+
//#endregion
|
|
9430
9419
|
//#region src/services/world-service.ts
|
|
9431
9420
|
const ARKME_WORLD_IMAGE_REF_TTL_MILLIS = 900 * 1e3;
|
|
9432
9421
|
const MAX_ARKME_WORLD_IMAGE_REFS = 2048;
|
|
@@ -9434,9 +9423,50 @@ const ARKME_WORLD_RECORD_REF_TTL_MILLIS = 900 * 1e3;
|
|
|
9434
9423
|
const MAX_ARKME_WORLD_RECORD_REFS = 4096;
|
|
9435
9424
|
const ARKME_VOICEPRINT_PLAY_SCOPE = 2;
|
|
9436
9425
|
const ARKME_VOICEPRINT_INVITE_TOKEN_MAX_LENGTH = 2048;
|
|
9426
|
+
const ARKME_VOICEPRINT_SOCIAL_CACHE_MILLIS = 300 * 1e3;
|
|
9427
|
+
const ARKME_VOICEPRINT_SOCIAL_STALE_MILLIS = 1440 * 60 * 1e3;
|
|
9428
|
+
const ARKME_VOICEPRINT_SOCIAL_SOURCE_TIMEOUT_MILLIS = 4e3;
|
|
9429
|
+
const WORLD_VOICEPRINT_SOCIAL_RELATIONS = {
|
|
9430
|
+
reciprocal_expectation: {
|
|
9431
|
+
type: "reciprocal_expectation",
|
|
9432
|
+
displayLine: "TA也曾期待过你的声音",
|
|
9433
|
+
reasonCode: "relationship_reciprocal_expectation",
|
|
9434
|
+
reasonLabel: "因为TA也曾期待过我的声音"
|
|
9435
|
+
},
|
|
9436
|
+
call: {
|
|
9437
|
+
type: "call",
|
|
9438
|
+
displayLine: "你们曾经通过话",
|
|
9439
|
+
reasonCode: "relationship_call",
|
|
9440
|
+
reasonLabel: "因为我们曾经通过话"
|
|
9441
|
+
},
|
|
9442
|
+
world_interaction: {
|
|
9443
|
+
type: "world_interaction",
|
|
9444
|
+
displayLine: "你们曾在世界回应过彼此",
|
|
9445
|
+
reasonCode: "relationship_world",
|
|
9446
|
+
reasonLabel: "因为我们在世界里回应过彼此"
|
|
9447
|
+
},
|
|
9448
|
+
group_interaction: {
|
|
9449
|
+
type: "group_interaction",
|
|
9450
|
+
displayLine: "你们曾在同一个群里互动过",
|
|
9451
|
+
reasonCode: "relationship_group",
|
|
9452
|
+
reasonLabel: "因为我们在群里有过互动"
|
|
9453
|
+
},
|
|
9454
|
+
private_chat: {
|
|
9455
|
+
type: "private_chat",
|
|
9456
|
+
displayLine: "你们曾经聊过",
|
|
9457
|
+
reasonCode: "relationship_chat",
|
|
9458
|
+
reasonLabel: "因为我们以前聊过"
|
|
9459
|
+
}
|
|
9460
|
+
};
|
|
9437
9461
|
function numberValue(value) {
|
|
9438
9462
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
9439
9463
|
}
|
|
9464
|
+
function integerValue(value) {
|
|
9465
|
+
if (typeof value === "number" && Number.isFinite(value)) return Math.trunc(value);
|
|
9466
|
+
if (typeof value !== "string" || !/^-?\d+$/.test(value.trim())) return 0;
|
|
9467
|
+
const parsed = Number(value.trim());
|
|
9468
|
+
return Number.isSafeInteger(parsed) ? parsed : 0;
|
|
9469
|
+
}
|
|
9440
9470
|
function listValue(value) {
|
|
9441
9471
|
return Array.isArray(value) ? value : [];
|
|
9442
9472
|
}
|
|
@@ -9472,6 +9502,26 @@ function worldVisibility(checkStatus) {
|
|
|
9472
9502
|
if (checkStatus === 0 || checkStatus === 2 || checkStatus === 3) return "visible";
|
|
9473
9503
|
return "unknown";
|
|
9474
9504
|
}
|
|
9505
|
+
function worldPublicationResult(checkStatus) {
|
|
9506
|
+
const visibility = worldVisibility(checkStatus);
|
|
9507
|
+
if (visibility === "rejected") return {
|
|
9508
|
+
recordSaved: true,
|
|
9509
|
+
recordState: "synced",
|
|
9510
|
+
worldPublished: false,
|
|
9511
|
+
visibility,
|
|
9512
|
+
checkStatus,
|
|
9513
|
+
retryable: false,
|
|
9514
|
+
error: "内容未通过审核,请调整后重试"
|
|
9515
|
+
};
|
|
9516
|
+
return {
|
|
9517
|
+
recordSaved: true,
|
|
9518
|
+
recordState: "synced",
|
|
9519
|
+
worldPublished: true,
|
|
9520
|
+
visibility,
|
|
9521
|
+
checkStatus,
|
|
9522
|
+
retryable: false
|
|
9523
|
+
};
|
|
9524
|
+
}
|
|
9475
9525
|
function worldTags(text) {
|
|
9476
9526
|
return [...text.matchAll(/#(\S+)/gu)].map((match) => match[1] ?? "").filter((tag) => tag !== "");
|
|
9477
9527
|
}
|
|
@@ -9479,6 +9529,10 @@ function stableWorldInteractionRecordUid(userId, targetRecordUid, clientMutation
|
|
|
9479
9529
|
const hex = createHash("sha256").update(`dsh-arkme:world-interaction:${String(userId)}:${targetRecordUid}:${clientMutationId}`).digest("hex");
|
|
9480
9530
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-5${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
|
|
9481
9531
|
}
|
|
9532
|
+
function stableWorldPublishRecordUid(userId, clientMutationId) {
|
|
9533
|
+
const hex = createHash("sha256").update(`dsh-arkme:world-publish:${String(userId)}:${clientMutationId}`).digest("hex");
|
|
9534
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-5${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
|
|
9535
|
+
}
|
|
9482
9536
|
function allowedSignedImageHost(environment, hostname) {
|
|
9483
9537
|
return (environment === "prod" ? ["jotmo-userfiles.oss-cn-hangzhou.aliyuncs.com", "userfiles.jotmo.cc"] : ["jotmo-userfiles-test.oss-cn-hangzhou.aliyuncs.com", "jotmo-userfiles.senguo.me"]).includes(hostname.toLowerCase());
|
|
9484
9538
|
}
|
|
@@ -9518,6 +9572,8 @@ var WorldService = class {
|
|
|
9518
9572
|
record;
|
|
9519
9573
|
worldImageRefs = /* @__PURE__ */ new Map();
|
|
9520
9574
|
worldRecordRefs = /* @__PURE__ */ new Map();
|
|
9575
|
+
voiceprintSocialCache = /* @__PURE__ */ new Map();
|
|
9576
|
+
voiceprintSocialInFlight = /* @__PURE__ */ new Map();
|
|
9521
9577
|
constructor(runtime, profile, media, record) {
|
|
9522
9578
|
this.runtime = runtime;
|
|
9523
9579
|
this.profile = profile;
|
|
@@ -9527,6 +9583,8 @@ var WorldService = class {
|
|
|
9527
9583
|
dispose() {
|
|
9528
9584
|
this.worldImageRefs.clear();
|
|
9529
9585
|
this.worldRecordRefs.clear();
|
|
9586
|
+
this.voiceprintSocialCache.clear();
|
|
9587
|
+
this.voiceprintSocialInFlight.clear();
|
|
9530
9588
|
}
|
|
9531
9589
|
async listWorldRecords(options = {}) {
|
|
9532
9590
|
const limit = Math.min(20, Math.max(1, Math.trunc(options.limit ?? 10)));
|
|
@@ -9589,6 +9647,37 @@ var WorldService = class {
|
|
|
9589
9647
|
...hasMore ? { nextOffset } : {}
|
|
9590
9648
|
};
|
|
9591
9649
|
}
|
|
9650
|
+
async listUserWorldFeed(userId, options = {}) {
|
|
9651
|
+
if (!Number.isSafeInteger(userId) || userId <= 0) throw new ArkmePluginError("world-user-id-invalid", "世界用户 ID 无效,请刷新后重试", false, 400);
|
|
9652
|
+
const session = await this.runtime.requireSession();
|
|
9653
|
+
const limit = Math.min(20, Math.max(1, Math.trunc(options.limit ?? 20)));
|
|
9654
|
+
let offset = Math.max(0, Math.trunc(options.offset ?? 0));
|
|
9655
|
+
let total = 0;
|
|
9656
|
+
let items = [];
|
|
9657
|
+
let hasMore = false;
|
|
9658
|
+
let attempts = 0;
|
|
9659
|
+
do {
|
|
9660
|
+
const data = await this.runtime.post(this.runtime.config.worldBaseUrl, "/api/public/v1/public-record/user-list", {
|
|
9661
|
+
user_id: userId,
|
|
9662
|
+
limit,
|
|
9663
|
+
offset
|
|
9664
|
+
}, void 0, [200], options.signal);
|
|
9665
|
+
const rawItems = listValue(data.list);
|
|
9666
|
+
total = Math.max(0, Math.trunc(numberValue(data.total)));
|
|
9667
|
+
const rootItems = rawItems.filter((raw) => stringValue$1(objectValue$1(raw).parent_record_uid).trim() === "");
|
|
9668
|
+
const resolvedAvatars = await this.resolveWorldAvatarUrls(rootItems, session, options.signal);
|
|
9669
|
+
items = (await Promise.all(rootItems.map((raw) => this.worldFeedItem(raw, session.userId, resolvedAvatars)))).filter((item) => item !== void 0);
|
|
9670
|
+
offset += rawItems.length;
|
|
9671
|
+
hasMore = rawItems.length > 0 && offset < total;
|
|
9672
|
+
attempts += 1;
|
|
9673
|
+
} while (items.length === 0 && hasMore && attempts < 4);
|
|
9674
|
+
return {
|
|
9675
|
+
items,
|
|
9676
|
+
total,
|
|
9677
|
+
hasMore,
|
|
9678
|
+
...hasMore ? { nextOffset: offset } : {}
|
|
9679
|
+
};
|
|
9680
|
+
}
|
|
9592
9681
|
async worldVoiceprintPlaybackAvailability(recordRefs, signal) {
|
|
9593
9682
|
const session = await this.runtime.requireSession();
|
|
9594
9683
|
const normalizedRefs = [...new Set(recordRefs.map((value) => value.trim()).filter((value) => value !== ""))].slice(0, 20);
|
|
@@ -9650,6 +9739,37 @@ var WorldService = class {
|
|
|
9650
9739
|
chunkEndRune
|
|
9651
9740
|
};
|
|
9652
9741
|
}
|
|
9742
|
+
async worldVoiceprintSocialContext(recordRef, options = {}) {
|
|
9743
|
+
const session = await this.runtime.requireSession();
|
|
9744
|
+
const entry = this.openWorldRecordRef(recordRef, session.userId);
|
|
9745
|
+
const authorUserId = entry.ownerUserId ?? 0;
|
|
9746
|
+
if (!Number.isSafeInteger(authorUserId) || authorUserId <= 0 || authorUserId === session.userId) return { relations: [] };
|
|
9747
|
+
const cacheKey = `${String(session.userId)}:${String(authorUserId)}`;
|
|
9748
|
+
const cached = this.voiceprintSocialCache.get(cacheKey);
|
|
9749
|
+
const age = cached === void 0 ? Number.POSITIVE_INFINITY : Date.now() - cached.savedAtMillis;
|
|
9750
|
+
if (options.forceRefresh !== true && cached !== void 0 && cached.context.relations.length > 0 && age < ARKME_VOICEPRINT_SOCIAL_CACHE_MILLIS) return cached.context;
|
|
9751
|
+
if (options.forceRefresh !== true && cached !== void 0 && cached.context.relations.length > 0 && age < ARKME_VOICEPRINT_SOCIAL_STALE_MILLIS) {
|
|
9752
|
+
this.refreshWorldVoiceprintSocialContext({
|
|
9753
|
+
cacheKey,
|
|
9754
|
+
flightKey: `${cacheKey}:${entry.recordUid}`,
|
|
9755
|
+
viewerUserId: session.userId,
|
|
9756
|
+
authorUserId,
|
|
9757
|
+
recordUid: entry.recordUid,
|
|
9758
|
+
fallback: cached,
|
|
9759
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
9760
|
+
});
|
|
9761
|
+
return cached.context;
|
|
9762
|
+
}
|
|
9763
|
+
return await this.refreshWorldVoiceprintSocialContext({
|
|
9764
|
+
cacheKey,
|
|
9765
|
+
flightKey: `${cacheKey}:${entry.recordUid}`,
|
|
9766
|
+
viewerUserId: session.userId,
|
|
9767
|
+
authorUserId,
|
|
9768
|
+
recordUid: entry.recordUid,
|
|
9769
|
+
...cached === void 0 ? {} : { fallback: cached },
|
|
9770
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
9771
|
+
});
|
|
9772
|
+
}
|
|
9653
9773
|
async createWorldVoiceprintInviteIntent(recordRef, signal) {
|
|
9654
9774
|
const session = await this.runtime.requireSession();
|
|
9655
9775
|
const entry = this.openWorldRecordRef(recordRef, session.userId);
|
|
@@ -9672,6 +9792,183 @@ var WorldService = class {
|
|
|
9672
9792
|
...entry.textPreview === void 0 ? {} : { textPreview: entry.textPreview }
|
|
9673
9793
|
};
|
|
9674
9794
|
}
|
|
9795
|
+
refreshWorldVoiceprintSocialContext(input) {
|
|
9796
|
+
const existing = this.voiceprintSocialInFlight.get(input.flightKey);
|
|
9797
|
+
if (existing !== void 0) return existing;
|
|
9798
|
+
const refresh = this.loadWorldVoiceprintSocialContext(input).then((result) => {
|
|
9799
|
+
const context = this.mergeWorldVoiceprintSocialContexts(input.fallback?.context, result.context);
|
|
9800
|
+
if (context.relations.length > 0 || result.allSourcesSucceeded) this.voiceprintSocialCache.set(input.cacheKey, {
|
|
9801
|
+
context,
|
|
9802
|
+
savedAtMillis: Date.now()
|
|
9803
|
+
});
|
|
9804
|
+
return context;
|
|
9805
|
+
}).catch(() => input.fallback?.context.relations.length ? input.fallback.context : { relations: [] }).finally(() => {
|
|
9806
|
+
this.voiceprintSocialInFlight.delete(input.flightKey);
|
|
9807
|
+
});
|
|
9808
|
+
this.voiceprintSocialInFlight.set(input.flightKey, refresh);
|
|
9809
|
+
return refresh;
|
|
9810
|
+
}
|
|
9811
|
+
async loadWorldVoiceprintSocialContext(input) {
|
|
9812
|
+
const session = await this.runtime.requireSession();
|
|
9813
|
+
const directChat = this.loadWorldVoiceprintDirectChat(input.authorUserId, session, input.signal);
|
|
9814
|
+
const results = await Promise.all([
|
|
9815
|
+
this.guardWorldVoiceprintSocialSource(async () => await this.loadWorldVoiceprintReciprocalExpectation(input.authorUserId, session, input.signal)),
|
|
9816
|
+
this.guardWorldVoiceprintSocialSource(async () => await this.loadWorldVoiceprintInterwovenRelations(input.authorUserId, directChat, session, input.signal)),
|
|
9817
|
+
this.guardWorldVoiceprintSocialSource(async () => await this.loadWorldVoiceprintPrivateChatRelation(input.authorUserId, directChat)),
|
|
9818
|
+
this.guardWorldVoiceprintSocialSource(async () => await this.loadWorldVoiceprintCommentRelation(input.viewerUserId, input.recordUid, session, input.signal))
|
|
9819
|
+
]);
|
|
9820
|
+
return {
|
|
9821
|
+
context: { relations: this.dedupeWorldVoiceprintRelations(results.flatMap((result) => result.relations)) },
|
|
9822
|
+
allSourcesSucceeded: results.every((result) => result.succeeded)
|
|
9823
|
+
};
|
|
9824
|
+
}
|
|
9825
|
+
async guardWorldVoiceprintSocialSource(loader) {
|
|
9826
|
+
let timeout;
|
|
9827
|
+
try {
|
|
9828
|
+
return await Promise.race([loader(), new Promise((resolve) => {
|
|
9829
|
+
timeout = setTimeout(() => {
|
|
9830
|
+
resolve({
|
|
9831
|
+
succeeded: false,
|
|
9832
|
+
relations: []
|
|
9833
|
+
});
|
|
9834
|
+
}, ARKME_VOICEPRINT_SOCIAL_SOURCE_TIMEOUT_MILLIS);
|
|
9835
|
+
})]);
|
|
9836
|
+
} catch {
|
|
9837
|
+
return {
|
|
9838
|
+
succeeded: false,
|
|
9839
|
+
relations: []
|
|
9840
|
+
};
|
|
9841
|
+
} finally {
|
|
9842
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
9843
|
+
}
|
|
9844
|
+
}
|
|
9845
|
+
async loadWorldVoiceprintReciprocalExpectation(authorUserId, session, signal) {
|
|
9846
|
+
return {
|
|
9847
|
+
succeeded: true,
|
|
9848
|
+
relations: listValue(objectValue$1((await this.runtime.authenticatedAudioPost("/api/v1/audio/voiceprint/world-enrollment-interactions", {}, session, signal, {
|
|
9849
|
+
lane: "interactive-read",
|
|
9850
|
+
key: "world-enrollment-interactions",
|
|
9851
|
+
cacheMs: 5e3
|
|
9852
|
+
})).received).requesters).some((raw) => {
|
|
9853
|
+
const requester = objectValue$1(raw);
|
|
9854
|
+
return integerValue(requester.user_id ?? requester.userId) === authorUserId;
|
|
9855
|
+
}) ? [WORLD_VOICEPRINT_SOCIAL_RELATIONS.reciprocal_expectation] : []
|
|
9856
|
+
};
|
|
9857
|
+
}
|
|
9858
|
+
async loadWorldVoiceprintDirectChat(authorUserId, session, signal) {
|
|
9859
|
+
let pageCursor;
|
|
9860
|
+
const visited = /* @__PURE__ */ new Set();
|
|
9861
|
+
for (;;) {
|
|
9862
|
+
const data = await this.runtime.authenticatedChatPost("/api/v1/chats/list", {
|
|
9863
|
+
limit: 100,
|
|
9864
|
+
session_kind: 1,
|
|
9865
|
+
...pageCursor === void 0 ? {} : { page_cursor: pageCursor }
|
|
9866
|
+
}, session, signal, {
|
|
9867
|
+
lane: "interactive-read",
|
|
9868
|
+
bypassCache: true
|
|
9869
|
+
});
|
|
9870
|
+
for (const raw of listValue(data.items)) {
|
|
9871
|
+
const bundle = objectValue$1(raw);
|
|
9872
|
+
const chatSession = objectValue$1(bundle.session);
|
|
9873
|
+
const counterpart = objectValue$1(bundle.private_counterpart);
|
|
9874
|
+
const sessionKind = integerValue(chatSession.session_kind);
|
|
9875
|
+
if (sessionKind !== 1 && sessionKind !== 3 || integerValue(counterpart.user_id ?? counterpart.userId) !== authorUserId) continue;
|
|
9876
|
+
const latestPreview = objectValue$1(bundle.latest_preview);
|
|
9877
|
+
const latestRecord = objectValue$1(latestPreview.record);
|
|
9878
|
+
const latestRelation = objectValue$1(latestPreview.relation);
|
|
9879
|
+
const unread = objectValue$1(bundle.unread_snapshot);
|
|
9880
|
+
const sessionUid = stringValue$1(chatSession.chat_session_uid).trim();
|
|
9881
|
+
if (sessionUid === "") continue;
|
|
9882
|
+
const sharedTopicId = [
|
|
9883
|
+
chatSession,
|
|
9884
|
+
objectValue$1(chatSession.extra),
|
|
9885
|
+
objectValue$1(chatSession.policy_snapshot)
|
|
9886
|
+
].map((source) => integerValue(source.subject_id ?? source.subjectId ?? source.shared_topic_id ?? source.sharedTopicId)).find((value) => value > 0) ?? 0;
|
|
9887
|
+
const hasPrivateMessageEvidence = Object.keys(latestRecord).length > 0 || Object.keys(objectValue$1(latestRecord.payload)).length > 0 || stringValue$1(latestRecord.record_uid).trim() !== "" || stringValue$1(latestRelation.record_uid).trim() !== "" || integerValue(unread.session_last_seq ?? chatSession.last_seq) > 0;
|
|
9888
|
+
return {
|
|
9889
|
+
sessionUid,
|
|
9890
|
+
sharedTopicId: Math.max(0, sharedTopicId),
|
|
9891
|
+
hasPrivateMessageEvidence
|
|
9892
|
+
};
|
|
9893
|
+
}
|
|
9894
|
+
if (data.has_more !== true) return void 0;
|
|
9895
|
+
const nextCursor = objectValue$1(data.next_page_cursor);
|
|
9896
|
+
if (Object.keys(nextCursor).length === 0) throw new Error("voiceprint direct-chat pagination cursor missing");
|
|
9897
|
+
const identity = JSON.stringify(nextCursor);
|
|
9898
|
+
if (visited.has(identity)) throw new Error("voiceprint direct-chat pagination cursor repeated");
|
|
9899
|
+
visited.add(identity);
|
|
9900
|
+
pageCursor = nextCursor;
|
|
9901
|
+
}
|
|
9902
|
+
}
|
|
9903
|
+
async loadWorldVoiceprintInterwovenRelations(authorUserId, directChatFuture, session, signal) {
|
|
9904
|
+
const directChat = await directChatFuture;
|
|
9905
|
+
if (directChat === void 0 || authorUserId <= 0) return {
|
|
9906
|
+
succeeded: true,
|
|
9907
|
+
relations: []
|
|
9908
|
+
};
|
|
9909
|
+
const data = directChat.sharedTopicId > 0 ? await this.runtime.authenticatedWorldPost("/api/v1/interwoven-moments/summary", { subject_id: directChat.sharedTopicId }, session, signal, {
|
|
9910
|
+
lane: "interactive-read",
|
|
9911
|
+
bypassCache: true
|
|
9912
|
+
}) : await this.runtime.authenticatedChatPost("/api/v1/chats/interwoven/summary", {
|
|
9913
|
+
subject_id: 0,
|
|
9914
|
+
chat_session_uid: directChat.sessionUid
|
|
9915
|
+
}, session, signal, {
|
|
9916
|
+
lane: "interactive-read",
|
|
9917
|
+
bypassCache: true
|
|
9918
|
+
});
|
|
9919
|
+
const stats = listValue(objectValue$1(data.recent_card).total_stats);
|
|
9920
|
+
const countFor = (momentType) => {
|
|
9921
|
+
return integerValue(objectValue$1(stats.find((value) => integerValue(objectValue$1(value).moment_type) === momentType)).count);
|
|
9922
|
+
};
|
|
9923
|
+
const relations = [];
|
|
9924
|
+
const callSummary = data.call_summary;
|
|
9925
|
+
if ((callSummary !== null && typeof callSummary === "object" && !Array.isArray(callSummary) ? integerValue(objectValue$1(callSummary).total_call_count) : countFor(3)) > 0) relations.push(WORLD_VOICEPRINT_SOCIAL_RELATIONS.call);
|
|
9926
|
+
if (countFor(2) > 0) relations.push(WORLD_VOICEPRINT_SOCIAL_RELATIONS.world_interaction);
|
|
9927
|
+
const groupFromStatus = listValue(data.source_status).some((raw) => {
|
|
9928
|
+
const status = objectValue$1(raw);
|
|
9929
|
+
return integerValue(status.moment_type) === 1 && integerValue(status.item_count) > 0;
|
|
9930
|
+
});
|
|
9931
|
+
if (countFor(1) > 0 || groupFromStatus) relations.push(WORLD_VOICEPRINT_SOCIAL_RELATIONS.group_interaction);
|
|
9932
|
+
return {
|
|
9933
|
+
succeeded: true,
|
|
9934
|
+
relations
|
|
9935
|
+
};
|
|
9936
|
+
}
|
|
9937
|
+
async loadWorldVoiceprintPrivateChatRelation(authorUserId, directChatFuture) {
|
|
9938
|
+
const directChat = await directChatFuture;
|
|
9939
|
+
return {
|
|
9940
|
+
succeeded: true,
|
|
9941
|
+
relations: directChat !== void 0 && authorUserId > 0 && directChat.hasPrivateMessageEvidence ? [WORLD_VOICEPRINT_SOCIAL_RELATIONS.private_chat] : []
|
|
9942
|
+
};
|
|
9943
|
+
}
|
|
9944
|
+
async loadWorldVoiceprintCommentRelation(viewerUserId, recordUid, session, signal) {
|
|
9945
|
+
if (recordUid.trim() === "") return {
|
|
9946
|
+
succeeded: true,
|
|
9947
|
+
relations: []
|
|
9948
|
+
};
|
|
9949
|
+
return {
|
|
9950
|
+
succeeded: true,
|
|
9951
|
+
relations: listValue((await this.runtime.authenticatedWorldPost("/api/v1/public-record/extend-list", {
|
|
9952
|
+
record_uid: recordUid,
|
|
9953
|
+
limit: 100,
|
|
9954
|
+
offset: 0
|
|
9955
|
+
}, session, signal, {
|
|
9956
|
+
lane: "interactive-read",
|
|
9957
|
+
bypassCache: true
|
|
9958
|
+
})).list).some((raw) => {
|
|
9959
|
+
const item = objectValue$1(raw);
|
|
9960
|
+
return integerValue(item.user_id ?? item.userId) === viewerUserId;
|
|
9961
|
+
}) ? [WORLD_VOICEPRINT_SOCIAL_RELATIONS.world_interaction] : []
|
|
9962
|
+
};
|
|
9963
|
+
}
|
|
9964
|
+
dedupeWorldVoiceprintRelations(relations) {
|
|
9965
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9966
|
+
return relations.filter((relation) => !seen.has(relation.type) && seen.add(relation.type));
|
|
9967
|
+
}
|
|
9968
|
+
mergeWorldVoiceprintSocialContexts(previous, current) {
|
|
9969
|
+
if (previous === void 0 || previous.relations.length === 0) return current;
|
|
9970
|
+
return { relations: this.dedupeWorldVoiceprintRelations([...previous.relations, ...current.relations]) };
|
|
9971
|
+
}
|
|
9675
9972
|
async listWorldInteractions(recordRef, options = {}) {
|
|
9676
9973
|
const session = await this.runtime.requireSession();
|
|
9677
9974
|
const root = this.openWorldRecordRef(recordRef, session.userId);
|
|
@@ -9817,18 +10114,88 @@ var WorldService = class {
|
|
|
9817
10114
|
avatar: profile.avatarRef,
|
|
9818
10115
|
template_kind: 1
|
|
9819
10116
|
}, void 0, signal);
|
|
9820
|
-
|
|
9821
|
-
|
|
10117
|
+
return worldPublicationResult(Math.trunc(numberValue(published.check_status)));
|
|
10118
|
+
} catch (error) {
|
|
10119
|
+
try {
|
|
10120
|
+
if (await this.worldRecordIsPublic(normalizedUid, signal)) return {
|
|
10121
|
+
recordSaved: true,
|
|
10122
|
+
recordState: "synced",
|
|
10123
|
+
worldPublished: true,
|
|
10124
|
+
visibility: "unknown",
|
|
10125
|
+
checkStatus: 0,
|
|
10126
|
+
retryable: false
|
|
10127
|
+
};
|
|
10128
|
+
} catch {}
|
|
10129
|
+
return this.worldPublishFailure(true, error, "synced");
|
|
10130
|
+
}
|
|
10131
|
+
}
|
|
10132
|
+
async publishWorldText(input) {
|
|
10133
|
+
const session = await this.runtime.requireSession();
|
|
10134
|
+
const clientMutationId = input.clientMutationId.trim();
|
|
10135
|
+
if (!/^[A-Za-z0-9_-]{16,128}$/.test(clientMutationId)) throw new ArkmePluginError("world-publish-mutation-invalid", "发布请求标识无效,请重试", false);
|
|
10136
|
+
return await this.publishWorldTextForConversation(stableWorldPublishRecordUid(session.userId, clientMutationId), input.textContent);
|
|
10137
|
+
}
|
|
10138
|
+
async publishWorldFileAssets(input) {
|
|
10139
|
+
const session = await this.runtime.requireSession();
|
|
10140
|
+
const clientMutationId = input.clientMutationId.trim();
|
|
10141
|
+
const textContent = input.textContent.trim();
|
|
10142
|
+
if (!/^[A-Za-z0-9_-]{16,128}$/.test(clientMutationId)) throw new ArkmePluginError("world-publish-mutation-invalid", "发布请求标识无效,请重试", false);
|
|
10143
|
+
if (textContent === "" || textContent.length > this.runtime.config.maxTextLength) throw new ArkmePluginError("world-text-invalid", "世界内容为空或过长", false);
|
|
10144
|
+
if (input.fileAssets.length === 0 || input.fileAssets.length > 9 || input.fileAssets.some((asset) => !/^[A-Za-z0-9._:-]{8,256}$/.test(asset.fileAssetUid) || asset.fileName.trim() === "" || !asset.mimeType.toLowerCase().startsWith("image/") || !Number.isSafeInteger(asset.size) || asset.size <= 0 || asset.size > 20971520 || asset.fileKind !== 1)) throw new ArkmePluginError("world-publish-assets-invalid", "世界图片参数无效", false);
|
|
10145
|
+
let profile;
|
|
10146
|
+
try {
|
|
10147
|
+
const snapshot = await this.profile.refreshProfile();
|
|
10148
|
+
if (snapshot.profile === null) throw new ArkmePluginError("profile-unavailable", "无法读取当前 Arkme 账号资料", true);
|
|
10149
|
+
profile = snapshot.profile;
|
|
10150
|
+
} catch (error) {
|
|
10151
|
+
return this.worldPublishFailure(false, error);
|
|
10152
|
+
}
|
|
10153
|
+
if (profile.contact.phoneMasked === void 0) return {
|
|
10154
|
+
recordSaved: false,
|
|
10155
|
+
recordState: "not_saved",
|
|
10156
|
+
worldPublished: false,
|
|
10157
|
+
visibility: "not_published",
|
|
10158
|
+
checkStatus: 0,
|
|
10159
|
+
retryable: false,
|
|
10160
|
+
error: "请先在 Arkme 客户端绑定手机号,再发到世界"
|
|
10161
|
+
};
|
|
10162
|
+
const recordUid = stableWorldPublishRecordUid(session.userId, clientMutationId);
|
|
10163
|
+
try {
|
|
10164
|
+
if (await this.worldRecordIsPublic(recordUid)) return {
|
|
9822
10165
|
recordSaved: true,
|
|
9823
10166
|
recordState: "synced",
|
|
9824
10167
|
worldPublished: true,
|
|
9825
|
-
visibility:
|
|
9826
|
-
checkStatus,
|
|
10168
|
+
visibility: "unknown",
|
|
10169
|
+
checkStatus: 0,
|
|
9827
10170
|
retryable: false
|
|
9828
10171
|
};
|
|
10172
|
+
} catch {}
|
|
10173
|
+
try {
|
|
10174
|
+
await this.record.createFileAssetsForConversation(recordUid, textContent, input.fileAssets);
|
|
10175
|
+
} catch (error) {
|
|
10176
|
+
return this.worldPublishFailure(false, error);
|
|
10177
|
+
}
|
|
10178
|
+
try {
|
|
10179
|
+
const published = await this.runtime.authenticatedWorldPost("/api/v1/public-record/publish-with-file-assets", {
|
|
10180
|
+
record_uid: recordUid,
|
|
10181
|
+
content: textContent,
|
|
10182
|
+
text_content: textContent,
|
|
10183
|
+
file_assets: input.fileAssets.map((asset, index) => ({
|
|
10184
|
+
file_asset_uid: asset.fileAssetUid,
|
|
10185
|
+
media_type: "image",
|
|
10186
|
+
file_kind: 1,
|
|
10187
|
+
sort_order: index
|
|
10188
|
+
})),
|
|
10189
|
+
tags: worldTags(textContent),
|
|
10190
|
+
original_topic_id: 0,
|
|
10191
|
+
created_at: Date.now(),
|
|
10192
|
+
nick_name: profile.nickname || profile.displayName,
|
|
10193
|
+
avatar: profile.avatarRef
|
|
10194
|
+
}, session);
|
|
10195
|
+
return worldPublicationResult(Math.trunc(numberValue(published.check_status)));
|
|
9829
10196
|
} catch (error) {
|
|
9830
10197
|
try {
|
|
9831
|
-
if (await this.worldRecordIsPublic(
|
|
10198
|
+
if (await this.worldRecordIsPublic(recordUid)) return {
|
|
9832
10199
|
recordSaved: true,
|
|
9833
10200
|
recordState: "synced",
|
|
9834
10201
|
worldPublished: true,
|
|
@@ -10072,10 +10439,6 @@ var WorldService = class {
|
|
|
10072
10439
|
}
|
|
10073
10440
|
};
|
|
10074
10441
|
//#endregion
|
|
10075
|
-
//#region src/types.ts
|
|
10076
|
-
const ARKME_PROVIDER_CONTRACT_VERSION = 1;
|
|
10077
|
-
const ARKME_DEFAULT_SHARE_WEBSITE = "https://app.arkme.ai";
|
|
10078
|
-
//#endregion
|
|
10079
10442
|
//#region src/arkme-service.ts
|
|
10080
10443
|
function worldVoiceprintInviteMessage(input) {
|
|
10081
10444
|
return `${input.textPreview === void 0 ? "我想邀请你开启声纹。" : `我看到你在世界里发的「${input.textPreview}」,想邀请你开启声纹。`}\n以后看到你的世界动态时,可以直接听到你的声音。\n${input.inviteUrl}`;
|
|
@@ -10277,13 +10640,13 @@ var ArkmeService = class {
|
|
|
10277
10640
|
extensionPreviews: true,
|
|
10278
10641
|
worldFeed: true,
|
|
10279
10642
|
worldInteractions: true,
|
|
10643
|
+
worldPublish: true,
|
|
10280
10644
|
worldVoiceprintPlayback: true,
|
|
10281
10645
|
worldVoiceprintInvite: true,
|
|
10646
|
+
worldVoiceprintSocialContext: true,
|
|
10282
10647
|
arrangements: true,
|
|
10283
10648
|
myExtensions: true,
|
|
10284
10649
|
extensionPublish: true,
|
|
10285
|
-
recordingTranscripts: true,
|
|
10286
|
-
recordingDoubaoBackfill: true,
|
|
10287
10650
|
extensionReviews: true,
|
|
10288
10651
|
...this.relatedRecording.isEnabled() ? { relatedRecordings: true } : {}
|
|
10289
10652
|
},
|
|
@@ -10370,12 +10733,8 @@ var ArkmeService = class {
|
|
|
10370
10733
|
return await this.recording.recordingCalendar(fromStamp, toStamp, signal);
|
|
10371
10734
|
}
|
|
10372
10735
|
/** Read-only Audio capability shared by the built-in UI and Arkme recording tools. */
|
|
10373
|
-
async recordingTranscript(dateStamp, signal
|
|
10374
|
-
return await this.recording.recordingTranscript(dateStamp, signal
|
|
10375
|
-
}
|
|
10376
|
-
/** Queue Doubao backfill only after an explicit UI, SDK, or Tool request. */
|
|
10377
|
-
async startRecordingDoubaoBackfill(dateStamp, signal) {
|
|
10378
|
-
return await this.recording.startRecordingDoubaoBackfill(dateStamp, signal);
|
|
10736
|
+
async recordingTranscript(dateStamp, signal) {
|
|
10737
|
+
return await this.recording.recordingTranscript(dateStamp, signal);
|
|
10379
10738
|
}
|
|
10380
10739
|
/** Read-only Audio capability shared by the built-in UI and Arkme recording tools. */
|
|
10381
10740
|
async recordingProjection(dateStamp, kind, signal) {
|
|
@@ -10726,12 +11085,18 @@ var ArkmeService = class {
|
|
|
10726
11085
|
async listMyWorldFeed(options = {}) {
|
|
10727
11086
|
return await this.world.listMyWorldFeed(options);
|
|
10728
11087
|
}
|
|
11088
|
+
async listUserWorldFeed(userId, options = {}) {
|
|
11089
|
+
return await this.world.listUserWorldFeed(userId, options);
|
|
11090
|
+
}
|
|
10729
11091
|
async worldVoiceprintPlaybackAvailability(recordRefs, signal) {
|
|
10730
11092
|
return await this.world.worldVoiceprintPlaybackAvailability(recordRefs, signal);
|
|
10731
11093
|
}
|
|
10732
11094
|
async generateWorldVoiceprintPlayback(input) {
|
|
10733
11095
|
return await this.world.generateWorldVoiceprintPlayback(input);
|
|
10734
11096
|
}
|
|
11097
|
+
async worldVoiceprintSocialContext(recordRef, options = {}) {
|
|
11098
|
+
return await this.world.worldVoiceprintSocialContext(recordRef, options);
|
|
11099
|
+
}
|
|
10735
11100
|
async inviteWorldVoiceprint(recordRef, signal) {
|
|
10736
11101
|
try {
|
|
10737
11102
|
const intent = await this.world.createWorldVoiceprintInviteIntent(recordRef, signal);
|
|
@@ -10772,6 +11137,12 @@ var ArkmeService = class {
|
|
|
10772
11137
|
async publishWorldTextForConversation(recordUid, textContent, signal) {
|
|
10773
11138
|
return await this.world.publishWorldTextForConversation(recordUid, textContent, signal);
|
|
10774
11139
|
}
|
|
11140
|
+
async publishWorldText(input) {
|
|
11141
|
+
return await this.world.publishWorldText(input);
|
|
11142
|
+
}
|
|
11143
|
+
async publishWorldFileAssets(input) {
|
|
11144
|
+
return await this.world.publishWorldFileAssets(input);
|
|
11145
|
+
}
|
|
10775
11146
|
async createText(recordUid, textContent) {
|
|
10776
11147
|
return await this.record.createText(recordUid, textContent);
|
|
10777
11148
|
}
|
|
@@ -12156,4 +12527,4 @@ async function invokePersistentArkmeExtension(extensionId, method, args) {
|
|
|
12156
12527
|
return jsonValue(await handler(jsonValue(args)));
|
|
12157
12528
|
}
|
|
12158
12529
|
//#endregion
|
|
12159
|
-
export { unpackArkmeExtension as A,
|
|
12530
|
+
export { unpackArkmeExtension as A, ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES as B, packBundleFiles as C, assertExtensionArtifactSize as D, renderArkmeSandboxHostEntry as E, ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE as F, ArkmePluginError as H, ArkmeService as I, ARKME_DEFAULT_SHARE_WEBSITE as L, ARKME_EXTENSION_ICON_MAX_BYTES as M, ARKME_EXTENSION_MAX_BYTES as N, canonicalExtensionJson as O, ARKME_EXTENSION_PREVIEW_MAX_BYTES as P, ARKME_PROVIDER_CONTRACT_VERSION as R, inspectNativeBundleArtifactV3 as S, readNativeBundleTarballV3 as T, ArkmeOutgoingCallError as U, isArkmeBotAvatarRef as V, ArkmeBundleArtifactError as _, persistentArkmeExtensionActive as a, canonicalBundleJson as b, readPersistentExtensionActivation as c, verifyBundleResolutionSignature as d, verifyExtensionResolutionSignature as f, ARKME_NATIVE_BUNDLE_ARTIFACT_KIND as g, ARKME_BUNDLE_MAX_BYTES as h, invokePersistentArkmeExtension as i, ARKME_EXTENSION_FORMAT as j, sha256Hex as k, writePersistentExtensionActivation as l, ARKME_BUNDLE_ARTIFACT_KIND as m, applyPersistentArkmeHostExtension as n, persistentArkmeExtensionRuntimeState as o, verifyNativeBundleResolutionSignature as p, deactivatePersistentArkmeExtension as r, materializePersistentExtensionBundle as s, activatePersistentArkmeExtension as t, renderArkmeBundleClientBundle as u, arkmeSandboxEntryId as v, packLocalNativeBundleDirectoryV3 as w, inspectBundleArtifact as x, bundleSha256 as y, ARKME_WORLD_PUBLISH_MAX_IMAGES as z };
|