@senguoyun/dsh-arkme 0.1.28 → 0.1.29

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.
Files changed (48) hide show
  1. package/lib/client.js +4257 -3404
  2. package/lib/client.js.map +1 -1
  3. package/lib/extension-profile-restart-helper.js +1 -1
  4. package/lib/index.js +314 -18
  5. package/lib/persistent-extension.js +1 -1
  6. package/lib/{persistent-runtime-CaPUsLwg.js → persistent-runtime-DLKV_LTp.js} +768 -380
  7. package/lib/{plugin-updater-helper-Ddppbids.js → plugin-updater-helper-BByro9U_.js} +1 -1
  8. package/lib/{plugin-updater-helper-Lmz7W2ph.js → plugin-updater-helper-BByw0ZyG.js} +171 -13
  9. package/lib/plugin-updater-helper.js +1 -1
  10. package/lib/types/arkme-service.d.ts +17 -4
  11. package/lib/types/arkme-service.d.ts.map +1 -1
  12. package/lib/types/billing-gateway.d.ts +28 -0
  13. package/lib/types/billing-gateway.d.ts.map +1 -0
  14. package/lib/types/client/ArkmeBillingSettings.d.ts +52 -0
  15. package/lib/types/client/ArkmeBillingSettings.d.ts.map +1 -0
  16. package/lib/types/client/ArkmeCallSurface.d.ts.map +1 -1
  17. package/lib/types/client/ArkmeLogin.d.ts +3 -1
  18. package/lib/types/client/ArkmeLogin.d.ts.map +1 -1
  19. package/lib/types/client/ArkmeSettingsSurface.d.ts +18 -0
  20. package/lib/types/client/ArkmeSettingsSurface.d.ts.map +1 -1
  21. package/lib/types/client/ArkmeSidebar.d.ts +3 -3
  22. package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
  23. package/lib/types/client/arkme-auth-flow.d.ts +1 -0
  24. package/lib/types/client/arkme-auth-flow.d.ts.map +1 -1
  25. package/lib/types/client/arkme-billing.d.ts +37 -0
  26. package/lib/types/client/arkme-billing.d.ts.map +1 -0
  27. package/lib/types/client/arkme-login-locales.d.ts +5 -0
  28. package/lib/types/client/arkme-login-locales.d.ts.map +1 -1
  29. package/lib/types/client/chat-directory-store.d.ts.map +1 -1
  30. package/lib/types/host-api.d.ts.map +1 -1
  31. package/lib/types/index.d.ts.map +1 -1
  32. package/lib/types/managed-ai/adapter.d.ts +20 -0
  33. package/lib/types/managed-ai/adapter.d.ts.map +1 -0
  34. package/lib/types/managed-ai/credential.d.ts +11 -0
  35. package/lib/types/managed-ai/credential.d.ts.map +1 -0
  36. package/lib/types/plugin-update-lifecycle-log.d.ts +17 -0
  37. package/lib/types/plugin-update-lifecycle-log.d.ts.map +1 -0
  38. package/lib/types/plugin-update.d.ts +3 -0
  39. package/lib/types/plugin-update.d.ts.map +1 -1
  40. package/lib/types/plugin-updater-helper.d.ts +1 -2
  41. package/lib/types/plugin-updater-helper.d.ts.map +1 -1
  42. package/lib/types/profile-plugin-entry.d.ts +6 -0
  43. package/lib/types/profile-plugin-entry.d.ts.map +1 -0
  44. package/lib/types/services/auth-service.d.ts +10 -0
  45. package/lib/types/services/auth-service.d.ts.map +1 -1
  46. package/lib/types/types.d.ts +56 -1
  47. package/lib/types/types.d.ts.map +1 -1
  48. package/package.json +12 -6
@@ -208,7 +208,7 @@ async function main() {
208
208
  if (planPath === void 0) throw new Error("extension restart plan path is required");
209
209
  const rawPlan = JSON.parse(await readFile(planPath, "utf8"));
210
210
  if (managed && isPluginUpdateRestartPlan(rawPlan)) {
211
- const pluginUpdate = await import("./plugin-updater-helper-Ddppbids.js");
211
+ const pluginUpdate = await import("./plugin-updater-helper-BByro9U_.js");
212
212
  if (mode === "--managed-finalize") {
213
213
  const healthUrl = process.argv[4];
214
214
  if (healthUrl === void 0) throw new Error("managed plugin update health URL is required");
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as securePrivateDirectory, c as securePrivateFileSync, i as prepareProfilePackageManager, n as isArkmeProfilePackageName, o as securePrivateDirectorySync, r as localExtensionPnpmArgs, s as securePrivateFile, t as applyArkmeProfileBundlePolicy } from "./profile-bundle-policy-CvojZuTD.js";
2
- import { A as readNativeBundleTarballV3, B as ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE, C as arkmeSandboxEntryId, D as inspectNativeBundleArtifactV3, E as inspectBundleArtifact, F as unpackArkmeExtension, H as validateVoiceprintPcm16Wav, I as ARKME_EXTENSION_FORMAT, J as ARKME_WORLD_PUBLISH_MAX_IMAGES, M as assertExtensionArtifactSize, N as canonicalExtensionJson, O as packBundleFiles, P as sha256Hex, Q as ArkmeOutgoingCallError, S as ArkmeBundleArtifactError, T as canonicalBundleJson, U as ARKME_DEFAULT_SHARE_WEBSITE, V as ArkmeService, W as ARKME_PROVIDER_CONTRACT_VERSION, X as isArkmeBotAvatarRef, Y as ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES, Z as ArkmePluginError, _ as verifyExtensionResolutionSignature, c as quarantinePersistentExtension, d as writePersistentExtensionActivation, f as renderArkmeBundleClientBundle, g as verifyBundleResolutionSignature, h as arkmeClientContentDigestFromSource, i as invokePersistentArkmeExtension, j as renderArkmeSandboxHostEntry, k as packLocalNativeBundleDirectoryV3, l as readPersistentExtensionActivation, m as arkmeClientContentDigest, o as persistentArkmeExtensionRuntimeState, p as activeProfileExtensionOwnerConflicts, r as deactivatePersistentArkmeExtension, s as materializePersistentExtensionBundle, t as activatePersistentArkmeExtension, u as refreshPersistentClientWrapper, v as verifyNativeBundleResolutionSignature, w as bundleSha256, x as ARKME_NATIVE_BUNDLE_ARTIFACT_KIND, y as ARKME_BUNDLE_ARTIFACT_KIND } from "./persistent-runtime-CaPUsLwg.js";
3
- import { _ as validatePluginUpdateArtifactOrigin, d as ARKME_PLUGIN_PACKAGE_NAME, f as PluginUpdateArtifactError, g as pluginUpdateEndpointUrl, h as parsePluginUpdateManifest, m as existingCachedPluginArtifactPath, n as buildTargetInstallArgs, o as reconcilePluginUpdaterProfilePolicy, p as downloadAndCachePluginArtifact, t as assertTargetArtifactIntegrity, u as PluginUpdateInstallStateStore, v as validatePluginUpdateServiceOrigin } from "./plugin-updater-helper-Lmz7W2ph.js";
2
+ import { A as readNativeBundleTarballV3, B as ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE, C as arkmeSandboxEntryId, D as inspectNativeBundleArtifactV3, E as inspectBundleArtifact, F as unpackArkmeExtension, H as validateVoiceprintPcm16Wav, I as ARKME_EXTENSION_FORMAT, J as ARKME_WORLD_PUBLISH_MAX_IMAGES, M as assertExtensionArtifactSize, N as canonicalExtensionJson, O as packBundleFiles, P as sha256Hex, Q as ArkmeOutgoingCallError, S as ArkmeBundleArtifactError, T as canonicalBundleJson, U as ARKME_DEFAULT_SHARE_WEBSITE, V as ArkmeService, W as ARKME_PROVIDER_CONTRACT_VERSION, X as isArkmeBotAvatarRef, Y as ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES, Z as ArkmePluginError, _ as verifyExtensionResolutionSignature, c as quarantinePersistentExtension, d as writePersistentExtensionActivation, f as renderArkmeBundleClientBundle, g as verifyBundleResolutionSignature, h as arkmeClientContentDigestFromSource, i as invokePersistentArkmeExtension, j as renderArkmeSandboxHostEntry, k as packLocalNativeBundleDirectoryV3, l as readPersistentExtensionActivation, m as arkmeClientContentDigest, o as persistentArkmeExtensionRuntimeState, p as activeProfileExtensionOwnerConflicts, r as deactivatePersistentArkmeExtension, s as materializePersistentExtensionBundle, t as activatePersistentArkmeExtension, u as refreshPersistentClientWrapper, v as verifyNativeBundleResolutionSignature, w as bundleSha256, x as ARKME_NATIVE_BUNDLE_ARTIFACT_KIND, y as ARKME_BUNDLE_ARTIFACT_KIND } from "./persistent-runtime-DLKV_LTp.js";
3
+ import { _ as parsePluginUpdateManifest, b as validatePluginUpdateServiceOrigin, d as writePluginUpdateLifecycleLog, f as PluginUpdateInstallStateStore, g as existingCachedPluginArtifactPath, h as downloadAndCachePluginArtifact, m as PluginUpdateArtifactError, n as buildTargetInstallArgs, o as reconcilePluginUpdaterProfilePolicy, p as ARKME_PLUGIN_PACKAGE_NAME, t as assertTargetArtifactIntegrity, u as detachManagedProfilePluginLink, v as pluginUpdateEndpointUrl, y as validatePluginUpdateArtifactOrigin } from "./plugin-updater-helper-BByw0ZyG.js";
4
4
  import { i as invokeArkmeBundle, n as arkmeBundleActive, r as deactivateArkmeBundle } from "./bundle-runtime-BTzRlc6V.js";
5
5
  import { t as ArkmeExtensionInstallStore } from "./install-store-C1tAM346.js";
6
6
  import { homedir } from "node:os";
@@ -17,11 +17,13 @@ import { defineTool } from "@deepseek-ai/dsh-tools";
17
17
  import { Readable } from "node:stream";
18
18
  import { pipeline } from "node:stream/promises";
19
19
  import { DatabaseSync } from "node:sqlite";
20
+ import { getOrCreateAnonymousUserId } from "@deepseek-ai/dsh-anonymous-user-id";
21
+ import { LlmAdapter, LlmError, ProviderRequestId, createUserMessage } from "@deepseek-ai/dsh-llm";
22
+ import { DeepSeekAdapter, resolveAdapterOptions } from "@deepseek-ai/dsh-llm-deepseek";
20
23
  import { Buffer as Buffer$1 } from "node:buffer";
21
24
  import { createServer } from "node:http";
22
25
  import sharp from "sharp";
23
26
  import { AttachmentError, AttachmentId } from "@deepseek-ai/dsh-attachment";
24
- import { createUserMessage } from "@deepseek-ai/dsh-llm";
25
27
  //#region src/openclaw/cli-adapter.ts
26
28
  const JOTMO_CHANNEL_PACKAGE = "@jotmo/openclaw-channel@0.1.12";
27
29
  function assertSucceeded(result, operation) {
@@ -507,7 +509,7 @@ function emptyState$1() {
507
509
  consecutiveFailures: 0
508
510
  };
509
511
  }
510
- function positiveNumber(value) {
512
+ function positiveNumber$1(value) {
511
513
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
512
514
  }
513
515
  function boundedString(value, maxLength) {
@@ -555,12 +557,12 @@ function parseState$1(raw) {
555
557
  const value = JSON.parse(raw);
556
558
  if (value === null || typeof value !== "object") return emptyState$1();
557
559
  const source = value;
558
- const lastCheckedAtMillis = positiveNumber(source.lastCheckedAtMillis);
559
- const lastSuccessfulCheckAtMillis = positiveNumber(source.lastSuccessfulCheckAtMillis);
560
+ const lastCheckedAtMillis = positiveNumber$1(source.lastCheckedAtMillis);
561
+ const lastSuccessfulCheckAtMillis = positiveNumber$1(source.lastSuccessfulCheckAtMillis);
560
562
  const lastKnownLatestVersion = boundedString(source.lastKnownLatestVersion, 128);
561
563
  const lastKnownNotice = normalizedNotice(source.lastKnownNotice);
562
564
  const acknowledgedVersion = boundedString(source.acknowledgedVersion, 128);
563
- const snoozedUntilMillis = positiveNumber(source.snoozedUntilMillis);
565
+ const snoozedUntilMillis = positiveNumber$1(source.snoozedUntilMillis);
564
566
  return {
565
567
  version: 1,
566
568
  ...lastCheckedAtMillis === void 0 ? {} : { lastCheckedAtMillis },
@@ -844,13 +846,24 @@ var ArkmePluginUpdateManager = class {
844
846
  const previous = await this.installStore.read();
845
847
  if (previous !== void 0 && ACTIVE_INSTALL_PHASES.has(previous.phase)) return previous;
846
848
  const runtime = this.installRuntime;
849
+ const jobId = randomUUID();
850
+ const logPath = runtime.harnessLogPath ?? join(this.stateDirectory, "plugin-update-helper.log");
851
+ const lifecycle = {
852
+ jobId,
853
+ previousVersion: this.installedVersion,
854
+ targetVersion: status.latestVersion
855
+ };
856
+ this.logInstallStage(logPath, lifecycle, "package-manager-preflight-started");
847
857
  try {
848
858
  (runtime.preparePackageManager ?? prepareProfilePackageManager)(runtime.dshHome, runtime.profileName);
859
+ this.logInstallStage(logPath, lifecycle, "package-manager-preflight-completed");
849
860
  } catch (error) {
850
- throw new ArkmePluginUpdateError("profile-package-manager-unavailable", `无法确认 DSH Profile 的 pnpm:${error instanceof Error ? error.message : String(error)}`, false);
861
+ const detail = error instanceof Error ? error.message : String(error);
862
+ this.logInstallStage(logPath, lifecycle, "package-manager-preflight-failed", { error: detail });
863
+ this.logInstallStage(logPath, lifecycle, "failed", { error: "profile-package-manager-unavailable" });
864
+ throw new ArkmePluginUpdateError("profile-package-manager-unavailable", `无法确认 DSH Profile 的 pnpm:${detail}`, false);
851
865
  }
852
866
  const execArgv = runtime.execArgv ?? process.execArgv;
853
- const jobId = randomUUID();
854
867
  const now = this.now();
855
868
  const snapshot = {
856
869
  schemaVersion: 1,
@@ -862,6 +875,7 @@ var ArkmePluginUpdateManager = class {
862
875
  updatedAtMillis: now
863
876
  };
864
877
  await this.installStore.write(snapshot);
878
+ this.logInstallStage(logPath, lifecycle, "preparing");
865
879
  let targetManifest = this.latestManifest?.version === status.latestVersion ? this.latestManifest : void 0;
866
880
  if (targetManifest === void 0) {
867
881
  await this.performCheck();
@@ -874,6 +888,8 @@ var ArkmePluginUpdateManager = class {
874
888
  message: "无法获取插件更新信息。",
875
889
  updatedAtMillis: this.now()
876
890
  });
891
+ this.logInstallStage(logPath, lifecycle, "manifest-missing");
892
+ this.logInstallStage(logPath, lifecycle, "failed", { error: "plugin-update-manifest-missing" });
877
893
  throw new ArkmePluginUpdateError("plugin-update-manifest-missing", "无法获取插件更新信息", true);
878
894
  }
879
895
  const cacheDirectory = join(this.stateDirectory, "plugin-cache");
@@ -883,6 +899,8 @@ var ArkmePluginUpdateManager = class {
883
899
  message: `正在下载 ${status.latestVersion}…`,
884
900
  updatedAtMillis: this.now()
885
901
  });
902
+ const downloadStartedAt = this.now();
903
+ this.logInstallStage(logPath, lifecycle, "downloading-started");
886
904
  let targetArtifactPath;
887
905
  try {
888
906
  targetArtifactPath = await downloadAndCachePluginArtifact(targetManifest, {
@@ -891,6 +909,7 @@ var ArkmePluginUpdateManager = class {
891
909
  fetchImpl: this.fetchImpl,
892
910
  requestTimeoutMs: this.requestTimeoutMs
893
911
  });
912
+ this.logInstallStage(logPath, lifecycle, "downloading-completed", { durationMs: Math.max(0, this.now() - downloadStartedAt) });
894
913
  } catch (error) {
895
914
  await this.installStore.write({
896
915
  ...snapshot,
@@ -898,6 +917,7 @@ var ArkmePluginUpdateManager = class {
898
917
  message: error instanceof Error ? `插件制品下载或校验失败:${error.message}` : "插件制品下载或校验失败。",
899
918
  updatedAtMillis: this.now()
900
919
  });
920
+ this.logInstallStage(logPath, lifecycle, "failed", { error: error instanceof Error ? error.message : String(error) });
901
921
  throw error instanceof ArkmePluginUpdateError ? error : error instanceof PluginUpdateArtifactError ? new ArkmePluginUpdateError(error.code, error.message, error.retryable) : new ArkmePluginUpdateError("plugin-update-artifact-invalid", "插件制品下载或校验失败", true);
902
922
  }
903
923
  await this.installStore.write({
@@ -906,9 +926,9 @@ var ArkmePluginUpdateManager = class {
906
926
  message: `插件 ${status.latestVersion} 已校验,准备安装…`,
907
927
  updatedAtMillis: this.now()
908
928
  });
929
+ this.logInstallStage(logPath, lifecycle, "verifying-completed");
909
930
  const previousArtifactPath = existingCachedPluginArtifactPath(cacheDirectory, this.installedVersion);
910
931
  const planPath = join(this.stateDirectory, `plugin-update-plan-${jobId}.json`);
911
- const logPath = join(this.stateDirectory, "plugin-update-helper.log");
912
932
  const disabledProfilePackages = [...new Set(runtime.disabledProfilePackages?.() ?? [])];
913
933
  if (disabledProfilePackages.length > 1e3 || disabledProfilePackages.some((packageName) => !isArkmeProfilePackageName(packageName))) throw new ArkmePluginUpdateError("plugin-update-profile-policy-invalid", "已关闭扩展的 Profile 状态无效", false);
914
934
  const plan = {
@@ -943,6 +963,7 @@ var ArkmePluginUpdateManager = class {
943
963
  message: `正在安装 ${status.latestVersion}…`,
944
964
  updatedAtMillis: this.now()
945
965
  });
966
+ this.logInstallStage(logPath, lifecycle, "installing");
946
967
  try {
947
968
  await this.installSupervisedProfilePlugin(plan, runtime);
948
969
  } catch (error) {
@@ -952,9 +973,17 @@ var ArkmePluginUpdateManager = class {
952
973
  message: error instanceof Error ? `新版本安装失败:${error.message}` : "新版本安装失败。",
953
974
  updatedAtMillis: this.now()
954
975
  });
976
+ this.logInstallStage(logPath, lifecycle, "failed", { error: error instanceof Error ? error.message : String(error) });
955
977
  throw new ArkmePluginUpdateError("plugin-update-install-failed", "新版本安装失败", true);
956
978
  }
957
- await this.writeSupervisedRestartPlan(runtime.supervisedPlanPath, plan);
979
+ this.logInstallStage(logPath, lifecycle, "restart-plan-writing");
980
+ try {
981
+ await this.writeSupervisedRestartPlan(runtime.supervisedPlanPath, plan);
982
+ this.logInstallStage(logPath, lifecycle, "restart-plan-written");
983
+ } catch (error) {
984
+ this.logInstallStage(logPath, lifecycle, "restart-plan-write-failed", { error: error instanceof Error ? error.message : String(error) });
985
+ throw error;
986
+ }
958
987
  const restarting = {
959
988
  ...snapshot,
960
989
  phase: "restarting",
@@ -962,15 +991,20 @@ var ArkmePluginUpdateManager = class {
962
991
  updatedAtMillis: this.now()
963
992
  };
964
993
  await this.installStore.write(restarting);
994
+ this.logInstallStage(logPath, lifecycle, "restarting");
965
995
  const exitProcess = runtime.requestProcessExit ?? ((code) => process.exit(code));
996
+ this.logInstallStage(logPath, lifecycle, "process-exit-scheduled");
966
997
  setTimeout(() => exitProcess(runtime.supervisedExitCode), 800).unref?.();
967
998
  return restarting;
968
999
  }
969
1000
  await writeFile(planPath, `${JSON.stringify(plan, void 0, 2)}\n`, { mode: 384 });
970
1001
  await chmod$1(planPath, 384);
1002
+ this.logInstallStage(logPath, lifecycle, "helper-spawn-started");
971
1003
  try {
972
1004
  await (runtime.spawnUpdater ?? this.spawnUpdater.bind(this))(planPath, logPath);
1005
+ this.logInstallStage(logPath, lifecycle, "helper-spawn-completed");
973
1006
  } catch (error) {
1007
+ this.logInstallStage(logPath, lifecycle, "helper-spawn-failed", { error: error instanceof Error ? error.message : String(error) });
974
1008
  await unlink(planPath).catch(() => void 0);
975
1009
  await this.installStore.write({
976
1010
  ...snapshot,
@@ -978,17 +1012,24 @@ var ArkmePluginUpdateManager = class {
978
1012
  message: "无法启动独立更新进程。",
979
1013
  updatedAtMillis: this.now()
980
1014
  });
1015
+ this.logInstallStage(logPath, lifecycle, "failed", { error: "plugin-update-helper-failed" });
981
1016
  throw new ArkmePluginUpdateError("plugin-update-helper-failed", "无法启动独立更新进程", true);
982
1017
  }
983
- (runtime.requestShutdown ?? (() => {
1018
+ const shutdown = runtime.requestShutdown ?? (() => {
984
1019
  setTimeout(() => process.kill(process.pid, "SIGTERM"), 800).unref?.();
985
- }))();
1020
+ });
1021
+ this.logInstallStage(logPath, lifecycle, "shutdown-requested");
1022
+ shutdown();
986
1023
  return snapshot;
987
1024
  }
988
1025
  async runProfilePluginAdd(plan) {
989
1026
  await this.runProfilePluginCommand(plan, buildTargetInstallArgs(plan), "安装");
990
1027
  }
991
1028
  async runProfilePluginRemove(plan) {
1029
+ await detachManagedProfilePluginLink({
1030
+ dshHome: plan.dshHome,
1031
+ profileName: plan.profileName
1032
+ });
992
1033
  await this.runProfilePluginCommand(plan, [
993
1034
  ...plan.execArgv,
994
1035
  plan.dshBinPath,
@@ -1027,23 +1068,57 @@ var ArkmePluginUpdateManager = class {
1027
1068
  async installSupervisedProfilePlugin(plan, runtime) {
1028
1069
  const add = runtime.runProfilePluginAdd ?? this.runProfilePluginAdd.bind(this);
1029
1070
  const remove = runtime.runProfilePluginRemove ?? this.runProfilePluginRemove.bind(this);
1071
+ const rollback = runtime.runProfilePluginRollback ?? this.runProfilePluginRollback.bind(this);
1072
+ const lifecycle = {
1073
+ jobId: plan.jobId,
1074
+ previousVersion: plan.previousVersion,
1075
+ targetVersion: plan.targetVersion
1076
+ };
1030
1077
  try {
1031
1078
  assertTargetArtifactIntegrity(plan);
1032
- await remove(plan);
1033
- await add(plan);
1079
+ const removeStartedAt = this.now();
1080
+ this.logInstallStage(plan.logPath, lifecycle, "profile-remove-started");
1081
+ try {
1082
+ await remove(plan);
1083
+ } catch (error) {
1084
+ this.logInstallStage(plan.logPath, lifecycle, "profile-remove-failed", { error: error instanceof Error ? error.message : String(error) });
1085
+ throw error;
1086
+ }
1087
+ this.logInstallStage(plan.logPath, lifecycle, "profile-remove-completed", { durationMs: Math.max(0, this.now() - removeStartedAt) });
1088
+ const addStartedAt = this.now();
1089
+ this.logInstallStage(plan.logPath, lifecycle, "profile-add-started");
1090
+ try {
1091
+ await add(plan);
1092
+ } catch (error) {
1093
+ this.logInstallStage(plan.logPath, lifecycle, "profile-add-failed", { error: error instanceof Error ? error.message : String(error) });
1094
+ throw error;
1095
+ }
1096
+ this.logInstallStage(plan.logPath, lifecycle, "profile-add-completed", { durationMs: Math.max(0, this.now() - addStartedAt) });
1034
1097
  reconcilePluginUpdaterProfilePolicy(plan);
1035
1098
  const installedVersion = this.readInstalledProfilePluginVersion(plan);
1036
- if (installedVersion !== plan.targetVersion) throw new Error(`DSH Profile 实际安装版本为 ${installedVersion || "未知"},预期为 ${plan.targetVersion}`);
1099
+ this.logInstallStage(plan.logPath, lifecycle, "installed-version-checked", { installedVersion });
1100
+ if (installedVersion !== plan.targetVersion) {
1101
+ this.logInstallStage(plan.logPath, lifecycle, "installed-version-mismatch", { installedVersion });
1102
+ throw new Error(`DSH Profile 实际安装版本为 ${installedVersion || "未知"},预期为 ${plan.targetVersion}`);
1103
+ }
1037
1104
  } catch (error) {
1105
+ this.logInstallStage(plan.logPath, lifecycle, "rollback-started");
1038
1106
  try {
1039
- await this.runProfilePluginRollback(plan);
1107
+ await rollback(plan);
1108
+ this.logInstallStage(plan.logPath, lifecycle, "rollback-completed");
1040
1109
  } catch (rollbackError) {
1041
1110
  const detail = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
1111
+ this.logInstallStage(plan.logPath, lifecycle, "rollback-failed", { error: detail });
1042
1112
  throw new Error(`插件安装失败,且恢复旧版本失败:${detail}`, { cause: error });
1043
1113
  }
1044
1114
  throw error;
1045
1115
  }
1046
1116
  }
1117
+ logInstallStage(logPath, context, stage, details = {}) {
1118
+ if (!writePluginUpdateLifecycleLog(logPath, context, stage, details)) try {
1119
+ this.logger.warn?.("dsh-arkme: unable to append plugin update lifecycle log jobId=%s stage=%s path=%s", context.jobId, stage, logPath);
1120
+ } catch {}
1121
+ }
1047
1122
  async runProfilePluginCommand(plan, args, operation) {
1048
1123
  try {
1049
1124
  await execFileAsync$2(plan.execPath, args, {
@@ -1359,6 +1434,21 @@ function writeJson$4(res, status, body) {
1359
1434
  function stringParam(params, key) {
1360
1435
  return typeof params[key] === "string" ? params[key] : "";
1361
1436
  }
1437
+ function billingIdentifierParam(params, key, code, message) {
1438
+ const value = stringParam(params, key).trim();
1439
+ if (value === "" || value.length > 256) throw new ArkmePluginError(code, message, false, 400);
1440
+ return value;
1441
+ }
1442
+ function billingUuidParam(params, key, code, message) {
1443
+ const value = stringParam(params, key).trim().toLowerCase();
1444
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value)) throw new ArkmePluginError(code, message, false, 400);
1445
+ return value;
1446
+ }
1447
+ function billingPaymentMethodParam(params) {
1448
+ const value = stringParam(params, "paymentMethod");
1449
+ if (value !== "alipay_pc_web" && value !== "wechat_native") throw new ArkmePluginError("billing-payment-method-invalid", "支付方式无效", false, 400);
1450
+ return value;
1451
+ }
1362
1452
  function numberParam(params, key, fallback) {
1363
1453
  const value = params[key];
1364
1454
  return typeof value === "number" && Number.isFinite(value) ? value : fallback;
@@ -1755,10 +1845,21 @@ async function dispatchArkmeHostOperation(service, operation, params, updateMana
1755
1845
  case "auth.config": return service.clientConfig();
1756
1846
  case "auth.begin": return await service.beginWechatLogin();
1757
1847
  case "auth.poll": return await service.pollWechatLogin(stringParam(params, "attemptId"));
1848
+ case "auth.app.begin": return await service.beginJiwoLogin();
1849
+ case "auth.app.poll": return await service.pollJiwoLogin(stringParam(params, "attemptId"));
1850
+ case "auth.app.cancel": return await service.cancelJiwoLogin(stringParam(params, "attemptId"));
1758
1851
  case "auth.test.login": return await service.testLogin(numberParam(params, "userId", 0));
1759
1852
  case "auth.phone.send": return await service.sendPhoneCode(stringParam(params, "phone"), captchaParam(params));
1760
1853
  case "auth.phone.verify": return await service.verifyPhoneCode(stringParam(params, "phone"), stringParam(params, "code"));
1761
1854
  case "auth.logout": return await service.logout();
1855
+ case "billing.quota": return await service.billingQuota();
1856
+ case "billing.products": return await service.billingProducts();
1857
+ case "billing.order.create": return await service.createBillingOrder({
1858
+ productId: billingIdentifierParam(params, "productId", "billing-product-id-invalid", "购买套餐无效"),
1859
+ paymentMethod: billingPaymentMethodParam(params),
1860
+ clientRequestId: billingUuidParam(params, "clientRequestId", "billing-client-request-id-invalid", "支付请求标识无效")
1861
+ });
1862
+ case "billing.order.status": return await service.billingOrderStatus(billingUuidParam(params, "orderId", "billing-order-id-invalid", "支付订单标识无效"));
1762
1863
  case "voiceprint.status": return await service.myVoiceprint();
1763
1864
  case "voiceprint.grants": return await service.outboundVoiceprintGrants({
1764
1865
  cursor: stringParam(params, "cursor").trim(),
@@ -3466,6 +3567,194 @@ var ArkmeLocalDatabase = class {
3466
3567
  }
3467
3568
  };
3468
3569
  //#endregion
3570
+ //#region src/managed-ai/adapter.ts
3571
+ const ARKME_MANAGED_PROVIDER = "arkme-managed";
3572
+ const ARKME_MANAGED_MODEL = "deepseek-v4-flash";
3573
+ const ARKME_MANAGED_PROVIDER_NAME = "Arkme";
3574
+ const ARKME_MANAGED_MODEL_DESCRIPTION = "使用 Arkme 登录,无需 API Key";
3575
+ const ARKME_INSUFFICIENT_BALANCE_MESSAGE = "Arkme AI 余额不足,请前往 Arkme 设置中的余额充值后重试";
3576
+ const ARKME_LOGIN_MESSAGE = "请先登录或重新登录 Arkme 后再使用托管模型";
3577
+ const ARKME_MANAGED_MODELS = /* @__PURE__ */ new Set([ARKME_MANAGED_MODEL]);
3578
+ const ARKME_AUTH_FAILURE_CODES = /* @__PURE__ */ new Set([
3579
+ "login-required",
3580
+ "login-expired",
3581
+ "auth-http-401",
3582
+ "auth-http-403"
3583
+ ]);
3584
+ function managedAiBaseUrl(intelligentBaseUrl) {
3585
+ return `${intelligentBaseUrl.replace(/\/+$/, "")}/api/v1/managed-ai`;
3586
+ }
3587
+ function asRecord(value) {
3588
+ return typeof value === "object" && value !== null ? value : void 0;
3589
+ }
3590
+ function validHttpStatus(value) {
3591
+ return typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599 ? value : void 0;
3592
+ }
3593
+ function positiveNumber(value) {
3594
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
3595
+ }
3596
+ function managedAiFailureFacts(error) {
3597
+ const source = asRecord(error);
3598
+ const failure = asRecord(source?.failure);
3599
+ const code = typeof failure?.code === "string" && failure.code !== "" ? failure.code : typeof source?.code === "string" && source.code !== "" ? source.code : "MANAGED_AI_FAILED";
3600
+ const status = validHttpStatus(failure?.status) ?? validHttpStatus(source?.status) ?? validHttpStatus(source?.httpStatus);
3601
+ const providerRetryAfterMs = positiveNumber(failure?.providerRetryAfterMs) ?? positiveNumber(source?.providerRetryAfterMs) ?? positiveNumber(source?.retryAfterMillis);
3602
+ const requestId = typeof failure?.requestId === "string" && failure.requestId !== "" ? failure.requestId : typeof source?.requestId === "string" && source.requestId !== "" ? source.requestId : void 0;
3603
+ return {
3604
+ code,
3605
+ ...status === void 0 ? {} : { status },
3606
+ ...providerRetryAfterMs === void 0 ? {} : { providerRetryAfterMs },
3607
+ ...requestId === void 0 ? {} : { requestId }
3608
+ };
3609
+ }
3610
+ function managedAiLocalizedFailure(facts) {
3611
+ if (facts.status === 402 || ["QUOTA", "INSUFFICIENT_BALANCE"].includes(facts.code)) return {
3612
+ code: "INSUFFICIENT_BALANCE",
3613
+ message: ARKME_INSUFFICIENT_BALANCE_MESSAGE
3614
+ };
3615
+ if (facts.status === 401 || facts.status === 403 || ["AUTH", "CREDENTIAL_UNAVAILABLE"].includes(facts.code)) return {
3616
+ code: "AUTH",
3617
+ message: ARKME_LOGIN_MESSAGE
3618
+ };
3619
+ if (facts.status === 429 || facts.code === "RATE_LIMIT") return {
3620
+ code: "RATE_LIMIT",
3621
+ message: "Arkme AI 请求过于频繁,请稍后重试"
3622
+ };
3623
+ if ([408, 504].includes(facts.status ?? 0) || facts.code === "TIMEOUT") return {
3624
+ code: "TIMEOUT",
3625
+ message: "Arkme AI 响应超时,请稍后重试"
3626
+ };
3627
+ if (facts.code === "TRANSPORT") return {
3628
+ code: "TRANSPORT",
3629
+ message: "无法连接 Arkme AI 服务,请检查网络后重试"
3630
+ };
3631
+ if (facts.code === "CONTEXT_WINDOW_EXCEEDED") return {
3632
+ code: facts.code,
3633
+ message: "对话内容过长,请新建对话或减少上下文后重试"
3634
+ };
3635
+ if (["UNKNOWN_MODEL", "NO_ADAPTER"].includes(facts.code)) return {
3636
+ code: facts.code,
3637
+ message: "当前 Arkme 模型不可用,请重新选择模型后重试"
3638
+ };
3639
+ if (facts.status === 400 || facts.status === 413 || facts.code === "INVALID_REQUEST") return {
3640
+ code: "INVALID_REQUEST",
3641
+ message: "请求内容不符合 Arkme AI 要求,请调整后重试"
3642
+ };
3643
+ if (facts.code === "ABORTED") return {
3644
+ code: facts.code,
3645
+ message: "本轮运行已取消"
3646
+ };
3647
+ if ([
3648
+ "EMPTY_RESPONSE",
3649
+ "MALFORMED_RESPONSE",
3650
+ "STREAM_CLOSED"
3651
+ ].includes(facts.code)) return {
3652
+ code: facts.code,
3653
+ message: "Arkme AI 返回异常,请重新发送消息"
3654
+ };
3655
+ if (facts.status !== void 0 && facts.status >= 500 || facts.code === "SERVER") return {
3656
+ code: "SERVER",
3657
+ message: "Arkme AI 服务暂不可用,请稍后重试"
3658
+ };
3659
+ return {
3660
+ code: facts.code,
3661
+ message: "Arkme AI 请求失败,请稍后重试"
3662
+ };
3663
+ }
3664
+ /** Convert provider and cross-module structured failures into stable Chinese user copy. */
3665
+ function localizeManagedAiError(error) {
3666
+ const facts = managedAiFailureFacts(error);
3667
+ const localized = managedAiLocalizedFailure(facts);
3668
+ return new LlmError(localized.message, localized.code, {
3669
+ cause: error,
3670
+ ...facts.status === void 0 ? {} : { status: facts.status },
3671
+ ...facts.providerRetryAfterMs === void 0 ? {} : { providerRetryAfterMs: facts.providerRetryAfterMs },
3672
+ ...facts.requestId === void 0 ? {} : { requestId: ProviderRequestId(facts.requestId) }
3673
+ });
3674
+ }
3675
+ function assertManagedRoute(provider, model) {
3676
+ if (provider !== "arkme-managed") throw new LlmError(`当前 Arkme 托管模型不支持提供商“${provider}”`, "NO_ADAPTER");
3677
+ if (model !== void 0 && !ARKME_MANAGED_MODELS.has(model)) throw new LlmError(`当前 Arkme 托管服务不支持模型“${model}”,请重新选择模型`, "UNKNOWN_MODEL");
3678
+ }
3679
+ async function resolveBearer(owner) {
3680
+ try {
3681
+ const bearer = (await owner.resolveManagedAccessCredential()).reveal();
3682
+ if (bearer !== "") return bearer;
3683
+ } catch (error) {
3684
+ const source = error;
3685
+ const sourceCode = typeof source.code === "string" ? source.code : "";
3686
+ const status = typeof source.httpStatus === "number" && Number.isInteger(source.httpStatus) && source.httpStatus >= 100 && source.httpStatus <= 599 ? source.httpStatus : void 0;
3687
+ const code = ARKME_AUTH_FAILURE_CODES.has(sourceCode) ? "AUTH" : sourceCode === "arkme-network-error" ? "TRANSPORT" : sourceCode === "arkme-timeout" || status === 504 ? "TIMEOUT" : status === 429 ? "RATE_LIMIT" : status !== void 0 && status >= 500 ? "SERVER" : "CREDENTIAL_UNAVAILABLE";
3688
+ const providerRetryAfterMs = typeof source.retryAfterMillis === "number" && Number.isFinite(source.retryAfterMillis) && source.retryAfterMillis > 0 ? source.retryAfterMillis : void 0;
3689
+ throw localizeManagedAiError(new LlmError("Arkme 托管模型凭据不可用", code, {
3690
+ cause: error,
3691
+ ...status === void 0 ? {} : { status },
3692
+ ...providerRetryAfterMs === void 0 ? {} : { providerRetryAfterMs }
3693
+ }));
3694
+ }
3695
+ throw new LlmError(ARKME_LOGIN_MESSAGE, "AUTH");
3696
+ }
3697
+ var ManagedAiLlmAdapter = class extends LlmAdapter {
3698
+ delegate;
3699
+ constructor(delegate) {
3700
+ super();
3701
+ this.delegate = delegate;
3702
+ }
3703
+ providerInfo(provider) {
3704
+ return {
3705
+ id: provider,
3706
+ name: ARKME_MANAGED_PROVIDER_NAME
3707
+ };
3708
+ }
3709
+ providerRetryPolicy(provider) {
3710
+ return this.delegate.providerRetryPolicy(provider);
3711
+ }
3712
+ listModels(provider) {
3713
+ assertManagedRoute(provider);
3714
+ return this.delegate.listModels(provider);
3715
+ }
3716
+ async resolveModel(provider, model, signal) {
3717
+ assertManagedRoute(provider, model);
3718
+ return await this.delegate.resolveModel(provider, model, signal);
3719
+ }
3720
+ async *stream(options) {
3721
+ assertManagedRoute(options.provider, options.model);
3722
+ try {
3723
+ yield* this.delegate.stream(options);
3724
+ } catch (error) {
3725
+ throw localizeManagedAiError(error);
3726
+ }
3727
+ }
3728
+ };
3729
+ function createManagedAiLlmAdapter(options) {
3730
+ const connection = resolveAdapterOptions({
3731
+ baseURL: managedAiBaseUrl(options.intelligentBaseUrl),
3732
+ thinking: "enabled",
3733
+ reasoningEffort: "high",
3734
+ maxTokens: 256e3,
3735
+ defaultContextWindow: 1e6,
3736
+ models: [{
3737
+ id: ARKME_MANAGED_MODEL,
3738
+ name: "DeepSeek-V4-Flash",
3739
+ description: ARKME_MANAGED_MODEL_DESCRIPTION,
3740
+ contextWindow: 1e6,
3741
+ maxTokens: 256e3
3742
+ }],
3743
+ retryPolicy: {
3744
+ mode: "normal",
3745
+ maxRetries: 0
3746
+ }
3747
+ });
3748
+ return new ManagedAiLlmAdapter(new DeepSeekAdapter({
3749
+ options: () => connection,
3750
+ resolveApiKey: async () => await resolveBearer(options.credentialOwner),
3751
+ resolveUserId: options.resolveAnonymousUserId ?? getOrCreateAnonymousUserId
3752
+ }));
3753
+ }
3754
+ function registerManagedAiProvider(ctx, options) {
3755
+ return ctx.llm.registerAdapter([ARKME_MANAGED_PROVIDER], createManagedAiLlmAdapter(options));
3756
+ }
3757
+ //#endregion
3469
3758
  //#region src/realtime-events.ts
3470
3759
  const HEARTBEAT_MS = 2e4;
3471
3760
  function isLoopback$2(address) {
@@ -14031,7 +14320,8 @@ function apply(ctx, config) {
14031
14320
  disabledProfilePackages: () => extensionStore.list().flatMap((item) => !item.enabled && item.profilePackageName !== void 0 ? [item.profilePackageName] : []),
14032
14321
  ...process.env.ARKME_DESKTOP_MANAGED_RESTART === "1" && process.env.ARKME_DESKTOP_MANAGED_RESTART_PLAN_PATH !== void 0 ? {
14033
14322
  supervisedExitCode: 75,
14034
- supervisedPlanPath: process.env.ARKME_DESKTOP_MANAGED_RESTART_PLAN_PATH
14323
+ supervisedPlanPath: process.env.ARKME_DESKTOP_MANAGED_RESTART_PLAN_PATH,
14324
+ ...process.env.ARKME_HARNESS_LOG_PATH === void 0 ? {} : { harnessLogPath: process.env.ARKME_HARNESS_LOG_PATH }
14035
14325
  } : {}
14036
14326
  }
14037
14327
  });
@@ -14066,6 +14356,12 @@ function apply(ctx, config) {
14066
14356
  let extensionInstallTasks;
14067
14357
  let ownedExtensionInventory;
14068
14358
  ctx.provide("arkmeData", service);
14359
+ ctx.inject(["llm"], (modelCtx) => {
14360
+ registerManagedAiProvider(modelCtx, {
14361
+ intelligentBaseUrl: config.intelligentBaseUrl,
14362
+ credentialOwner: service
14363
+ });
14364
+ });
14069
14365
  registerDSHAgentInputRecordSync(ctx, service);
14070
14366
  registerArkmeTools(ctx, service, config.toolProfile);
14071
14367
  ctx.inject(["dynamicCordisRunner", "agents"], (dynamicCtx) => {
@@ -1,2 +1,2 @@
1
- import { a as persistentArkmeExtensionActive, i as invokePersistentArkmeExtension, n as applyPersistentArkmeHostExtension, o as persistentArkmeExtensionRuntimeState, r as deactivatePersistentArkmeExtension, t as activatePersistentArkmeExtension } from "./persistent-runtime-CaPUsLwg.js";
1
+ import { a as persistentArkmeExtensionActive, i as invokePersistentArkmeExtension, n as applyPersistentArkmeHostExtension, o as persistentArkmeExtensionRuntimeState, r as deactivatePersistentArkmeExtension, t as activatePersistentArkmeExtension } from "./persistent-runtime-DLKV_LTp.js";
2
2
  export { activatePersistentArkmeExtension, applyPersistentArkmeHostExtension, deactivatePersistentArkmeExtension, invokePersistentArkmeExtension, persistentArkmeExtensionActive, persistentArkmeExtensionRuntimeState };