@openspecui/web 3.11.1 → 3.11.3

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 (70) hide show
  1. package/dist/assets/CanvasRenderer-DGnQw8uB.js +1 -0
  2. package/dist/assets/WebGLRenderer-DHRbteVS.js +1 -0
  3. package/dist/assets/WebGPURenderer-BnFcGKnW.js +1 -0
  4. package/dist/assets/browserAll-BB7WVzo0.js +1 -0
  5. package/dist/assets/dist-B0Que_Lt.js +1 -0
  6. package/dist/assets/dist-B8m1wxBF.js +1 -0
  7. package/dist/assets/{dist-DxmYOUGn.js → dist-BKY1RG9s.js} +1 -1
  8. package/dist/assets/{dist-B09y0Ph7.js → dist-BVKuVv2H.js} +1 -1
  9. package/dist/assets/{dist-DdsOxRxJ.js → dist-Bl4uejAA.js} +1 -1
  10. package/dist/assets/{dist--JzlUmDP.js → dist-CZh2GIVt.js} +1 -1
  11. package/dist/assets/{dist-Dx00xLFT.js → dist-Caq73PXT.js} +1 -1
  12. package/dist/assets/{dist-C9BN4134.js → dist-CkEGbci5.js} +1 -1
  13. package/dist/assets/{dist-rGlPGEMw.js → dist-DDPVC2MF.js} +1 -1
  14. package/dist/assets/dist-DP_rT4tp.js +1 -0
  15. package/dist/assets/{dist-BttXL4wz.js → dist-YXnB8lV1.js} +1 -1
  16. package/dist/assets/{dist-F0lgtwe2.js → dist-rlrlm1HB.js} +1 -1
  17. package/dist/assets/{init-C46YDZ2H.js → init-sSrVfvjg.js} +1 -1
  18. package/dist/assets/main-DThx1JaQ.js +1654 -0
  19. package/dist/assets/main-fCQ7khWW.css +1 -0
  20. package/dist/assets/trpc-Dko2Zn9y.js +1 -0
  21. package/dist/assets/webworkerAll-Bfbn1LyG.js +1 -0
  22. package/dist/index.html +2 -2
  23. package/dist-ssg/client/.vite/ssr-manifest.json +15 -15
  24. package/dist-ssg/client/assets/CanvasRenderer-Dpr5EYjp.js +1 -0
  25. package/dist-ssg/client/assets/WebGLRenderer-DCzH263Z.js +1 -0
  26. package/dist-ssg/client/assets/WebGPURenderer-DgF_8B9g.js +1 -0
  27. package/dist-ssg/client/assets/browserAll-CPl4rDmN.js +1 -0
  28. package/dist-ssg/client/assets/{dist-yriBIRgD.js → dist-BKTT7Vdm.js} +1 -1
  29. package/dist-ssg/client/assets/{dist-BRxWvz6j.js → dist-BPUIHtZ8.js} +1 -1
  30. package/dist-ssg/client/assets/dist-BuFVGK1x.js +1 -0
  31. package/dist-ssg/client/assets/{dist-Dg-rGFsy.js → dist-CLrPzzut.js} +1 -1
  32. package/dist-ssg/client/assets/{dist-hWAvow10.js → dist-CVizFqBj.js} +1 -1
  33. package/dist-ssg/client/assets/{dist-D_7Z5apg.js → dist-CX1-5rfl.js} +1 -1
  34. package/dist-ssg/client/assets/{dist-DjZdWHNx.js → dist-Cm5Vx6W8.js} +1 -1
  35. package/dist-ssg/client/assets/{dist-DOwxbW7B.js → dist-DJkx9TIh.js} +1 -1
  36. package/dist-ssg/client/assets/dist-DlrmChto.js +1 -0
  37. package/dist-ssg/client/assets/{dist-9ZjKnAh1.js → dist-HHQTTSi-.js} +1 -1
  38. package/dist-ssg/client/assets/dist-bnfyzoQu.js +1 -0
  39. package/dist-ssg/client/assets/{dist-BPn14NhJ.js → dist-upAmtw9_.js} +1 -1
  40. package/dist-ssg/client/assets/{ghostty-web-BVM0FkWD.js → ghostty-web-BKQcHDq5.js} +1 -1
  41. package/dist-ssg/client/assets/index-BtGAsAtP.css +1 -0
  42. package/dist-ssg/client/assets/index.ssg-DBq9_pDs.js +1624 -0
  43. package/dist-ssg/client/assets/{init-DBoYmUC7.js → init-brQ3KbKB.js} +1 -1
  44. package/dist-ssg/client/assets/trpc-DGapI9Ny.js +1 -0
  45. package/dist-ssg/client/assets/webworkerAll-BKMUeO96.js +1 -0
  46. package/dist-ssg/client/index.ssg.html +2 -2
  47. package/dist-ssg/server/entry-server.js +341 -119
  48. package/package.json +3 -3
  49. package/dist/assets/CanvasRenderer-Bs7UxSWT.js +0 -1
  50. package/dist/assets/WebGLRenderer-l71uR9MI.js +0 -1
  51. package/dist/assets/WebGPURenderer-tjCbVxRm.js +0 -1
  52. package/dist/assets/browserAll-BDY91DxA.js +0 -1
  53. package/dist/assets/dist-CCD9CqTu.js +0 -1
  54. package/dist/assets/dist-DjM_Envn.js +0 -1
  55. package/dist/assets/dist-UpX5-9sH.js +0 -1
  56. package/dist/assets/main-B2c4pZCT.css +0 -1
  57. package/dist/assets/main-Wj4p5q80.js +0 -1654
  58. package/dist/assets/trpc-1XzKnuJv.js +0 -1
  59. package/dist/assets/webworkerAll-CitYd6ji.js +0 -1
  60. package/dist-ssg/client/assets/CanvasRenderer-FPbXzOhu.js +0 -1
  61. package/dist-ssg/client/assets/WebGLRenderer-DTbkQ-Tc.js +0 -1
  62. package/dist-ssg/client/assets/WebGPURenderer-jYEtkBkX.js +0 -1
  63. package/dist-ssg/client/assets/browserAll-D2rErTpO.js +0 -1
  64. package/dist-ssg/client/assets/dist-03Q-XuhL.js +0 -1
  65. package/dist-ssg/client/assets/dist-CNXuEBuZ.js +0 -1
  66. package/dist-ssg/client/assets/dist-Dj9a_D4b.js +0 -1
  67. package/dist-ssg/client/assets/index-5OettMZv.css +0 -1
  68. package/dist-ssg/client/assets/index.ssg-C4D0iHIp.js +0 -1624
  69. package/dist-ssg/client/assets/trpc-J2T_izXe.js +0 -1
  70. package/dist-ssg/client/assets/webworkerAll-CLzsuMst.js +0 -1
@@ -32295,10 +32295,23 @@ ZodPipeline.create;
32295
32295
  var TranslationEngineIdSchema = enumType([
32296
32296
  "browser",
32297
32297
  "local",
32298
+ "local-ct2",
32299
+ "local-llama",
32298
32300
  "openai"
32299
32301
  ]);
32300
32302
  var DEFAULT_TRANSLATION_ENGINE_ID = "browser";
32301
- enumType(["local", "openai"]);
32303
+ function isManagedLocalTranslationEngineId(engineId) {
32304
+ return engineId === "local" || engineId === "local-ct2" || engineId === "local-llama";
32305
+ }
32306
+ function isDirectionalManagedLocalTranslationEngineId(engineId) {
32307
+ return engineId === "local" || engineId === "local-ct2";
32308
+ }
32309
+ enumType([
32310
+ "local",
32311
+ "local-ct2",
32312
+ "local-llama",
32313
+ "openai"
32314
+ ]);
32302
32315
  var LocalModelDownloadStatusSchema = enumType([
32303
32316
  "not-downloaded",
32304
32317
  "queued",
@@ -32411,7 +32424,11 @@ var LocalModelProfileLoadStateSchema = objectType({
32411
32424
  updatedAt: numberType().int().nonnegative().optional()
32412
32425
  });
32413
32426
  objectType({
32414
- engineId: literalType("local"),
32427
+ engineId: enumType([
32428
+ "local",
32429
+ "local-ct2",
32430
+ "local-llama"
32431
+ ]),
32415
32432
  modelId: stringType().min(1),
32416
32433
  selectedGroupId: stringType().min(1).optional(),
32417
32434
  groupId: stringType().min(1).optional(),
@@ -32460,6 +32477,77 @@ objectType({
32460
32477
  downloadedBytes: numberType().int().nonnegative().optional()
32461
32478
  })).default([])
32462
32479
  });
32480
+ enumType([
32481
+ "local",
32482
+ "network",
32483
+ "recommended"
32484
+ ]);
32485
+ var TranslationEngineDependencyStateSchema = enumType([
32486
+ "installed",
32487
+ "installing",
32488
+ "missing",
32489
+ "error",
32490
+ "not-applicable"
32491
+ ]);
32492
+ var TranslationEngineRuntimeStateSchema = enumType([
32493
+ "ready",
32494
+ "probing",
32495
+ "failed",
32496
+ "error",
32497
+ "not-applicable"
32498
+ ]);
32499
+ var TranslationEngineAssetStateSchema = enumType([
32500
+ "ready",
32501
+ "missing",
32502
+ "downloading",
32503
+ "error",
32504
+ "not-applicable"
32505
+ ]);
32506
+ var TranslationEngineLifecyclePhaseMetaSchema = objectType({
32507
+ message: stringType().optional(),
32508
+ progress: numberType().min(0).max(1).optional(),
32509
+ error: stringType().optional()
32510
+ });
32511
+ var TranslationEngineLifecycleStatusSchema = objectType({
32512
+ dependency: TranslationEngineLifecyclePhaseMetaSchema.extend({ state: TranslationEngineDependencyStateSchema }),
32513
+ runtime: TranslationEngineLifecyclePhaseMetaSchema.extend({ state: TranslationEngineRuntimeStateSchema }),
32514
+ assets: TranslationEngineLifecyclePhaseMetaSchema.extend({ state: TranslationEngineAssetStateSchema }),
32515
+ summary: stringType().optional()
32516
+ });
32517
+ function isTranslationEngineDependencyReady(status) {
32518
+ return status.dependency.state === "installed" || status.dependency.state === "not-applicable";
32519
+ }
32520
+ function isTranslationEngineRuntimeReady(status) {
32521
+ return status.runtime.state === "ready" || status.runtime.state === "not-applicable";
32522
+ }
32523
+ function shouldShowTranslationEngineInstallGate(status) {
32524
+ if (!status) return false;
32525
+ return !isTranslationEngineDependencyReady(status) || !isTranslationEngineRuntimeReady(status);
32526
+ }
32527
+ function getTranslationEngineLifecycleMessage(status) {
32528
+ if (!status) return void 0;
32529
+ return status.summary ?? status.runtime.error ?? status.runtime.message ?? status.dependency.error ?? status.dependency.message ?? status.assets.error ?? status.assets.message;
32530
+ }
32531
+ var TranslationEngineInstallLogStreamSchema = enumType(["stdout", "stderr"]);
32532
+ objectType({
32533
+ stream: TranslationEngineInstallLogStreamSchema,
32534
+ text: stringType()
32535
+ });
32536
+ discriminatedUnionType("type", [
32537
+ objectType({
32538
+ type: literalType("status"),
32539
+ lifecycle: TranslationEngineLifecycleStatusSchema
32540
+ }),
32541
+ objectType({
32542
+ type: literalType("log"),
32543
+ stream: TranslationEngineInstallLogStreamSchema,
32544
+ text: stringType()
32545
+ }),
32546
+ objectType({
32547
+ type: literalType("exit"),
32548
+ lifecycle: TranslationEngineLifecycleStatusSchema
32549
+ })
32550
+ ]);
32463
32551
  var TranslationOpenAISettingsSchema = objectType({
32464
32552
  baseUrl: stringType().default(""),
32465
32553
  token: stringType().default(""),
@@ -32470,9 +32558,21 @@ var TranslationLocalSettingsSchema = objectType({
32470
32558
  selectedGroupId: stringType().optional(),
32471
32559
  hfEndpoint: stringType().default("")
32472
32560
  });
32561
+ var TranslationLocalCt2SettingsSchema = objectType({
32562
+ model: stringType().default("ooeoeo/opus-mt-en-zh-ct2-float16"),
32563
+ selectedGroupId: stringType().optional(),
32564
+ hfEndpoint: stringType().default("")
32565
+ });
32566
+ var TranslationLocalLlamaSettingsSchema = objectType({
32567
+ model: stringType().default("bartowski/Qwen2.5-0.5B-Instruct-GGUF"),
32568
+ selectedGroupId: stringType().optional(),
32569
+ hfEndpoint: stringType().default("")
32570
+ });
32473
32571
  objectType({
32474
32572
  openai: TranslationOpenAISettingsSchema.default(TranslationOpenAISettingsSchema.parse({})),
32475
- local: TranslationLocalSettingsSchema.default(TranslationLocalSettingsSchema.parse({}))
32573
+ local: TranslationLocalSettingsSchema.default(TranslationLocalSettingsSchema.parse({})),
32574
+ localCt2: TranslationLocalCt2SettingsSchema.default(TranslationLocalCt2SettingsSchema.parse({})),
32575
+ localLlama: TranslationLocalLlamaSettingsSchema.default(TranslationLocalLlamaSettingsSchema.parse({}))
32476
32576
  });
32477
32577
  objectType({
32478
32578
  engineId: TranslationEngineIdSchema,
@@ -32494,6 +32594,14 @@ var TranslationEngineProjectSettingsSchema = objectType({
32494
32594
  model: stringType().min(1).optional(),
32495
32595
  selectedGroupId: stringType().min(1).optional()
32496
32596
  }).default({}),
32597
+ localCt2: objectType({
32598
+ model: stringType().min(1).optional(),
32599
+ selectedGroupId: stringType().min(1).optional()
32600
+ }).default({}),
32601
+ localLlama: objectType({
32602
+ model: stringType().min(1).optional(),
32603
+ selectedGroupId: stringType().min(1).optional()
32604
+ }).default({}),
32497
32605
  openai: objectType({ model: stringType().min(1).optional() }).default({})
32498
32606
  }).default({});
32499
32607
  var DocumentTranslationConfigSchema = objectType({
@@ -114602,77 +114710,6 @@ function navigateHashAnchor(anchorElement, hash) {
114602
114710
  return true;
114603
114711
  }
114604
114712
  //#endregion
114605
- //#region src/lib/document-translation-session-state.ts
114606
- var DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY = "openspecui:document-translation:mode";
114607
- var DEFAULT_ACTIVATION = "source";
114608
- var ACTIVATION_STORAGE_EVENT = "openspecui:document-translation-session-change";
114609
- function isDocumentTranslationActivation(value) {
114610
- return value === "source" || value === "translated";
114611
- }
114612
- function readDocumentTranslationActivation() {
114613
- if (typeof window === "undefined") return DEFAULT_ACTIVATION;
114614
- try {
114615
- const value = window.sessionStorage.getItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY);
114616
- return isDocumentTranslationActivation(value) ? value : DEFAULT_ACTIVATION;
114617
- } catch {
114618
- return DEFAULT_ACTIVATION;
114619
- }
114620
- }
114621
- function writeDocumentTranslationActivation(value) {
114622
- if (typeof window === "undefined") return;
114623
- try {
114624
- window.sessionStorage.setItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY, value);
114625
- } catch {
114626
- return;
114627
- }
114628
- window.dispatchEvent(new CustomEvent(ACTIVATION_STORAGE_EVENT, { detail: value }));
114629
- }
114630
- function useDocumentTranslationActivation() {
114631
- const [activation, setActivationState] = (0, import_react.useState)(readDocumentTranslationActivation);
114632
- (0, import_react.useEffect)(() => {
114633
- const handleActivationChange = () => {
114634
- setActivationState(readDocumentTranslationActivation());
114635
- };
114636
- window.addEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
114637
- window.addEventListener("storage", handleActivationChange);
114638
- return () => {
114639
- window.removeEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
114640
- window.removeEventListener("storage", handleActivationChange);
114641
- };
114642
- }, []);
114643
- return {
114644
- activation,
114645
- setActivation: (0, import_react.useCallback)((value) => {
114646
- writeDocumentTranslationActivation(value);
114647
- setActivationState(value);
114648
- }, [])
114649
- };
114650
- }
114651
- //#endregion
114652
- //#region src/lib/resolve-document-translation-config.ts
114653
- function resolveDocumentTranslationConfig(translationConfig, globalSettings) {
114654
- if (!translationConfig) return void 0;
114655
- const local = translationConfig.engines?.local ?? {};
114656
- const openai = translationConfig.engines?.openai ?? {};
114657
- const resolvedLocalModel = local.model ?? globalSettings?.translationEngines.local.model;
114658
- const resolvedLocalSelectedGroupId = local.selectedGroupId ?? globalSettings?.translationEngines.local.selectedGroupId;
114659
- const resolvedOpenAIModel = openai.model ?? globalSettings?.translationEngines.openai.model;
114660
- return {
114661
- ...translationConfig,
114662
- engines: {
114663
- local: {
114664
- ...local,
114665
- ...resolvedLocalModel ? { model: resolvedLocalModel } : {},
114666
- ...resolvedLocalSelectedGroupId ? { selectedGroupId: resolvedLocalSelectedGroupId } : {}
114667
- },
114668
- openai: {
114669
- ...openai,
114670
- ...resolvedOpenAIModel ? { model: resolvedOpenAIModel } : {}
114671
- }
114672
- }
114673
- };
114674
- }
114675
- //#endregion
114676
114713
  //#region ../browser-translator/dist/index.mjs
114677
114714
  async function scanBrowserTranslationSupportTable(options) {
114678
114715
  const translator = (options.win ?? window).Translator;
@@ -131358,8 +131395,9 @@ function createProjectionContext(lookup, annotations, projections) {
131358
131395
  //#endregion
131359
131396
  //#region ../core/src/translation-language-pair.ts
131360
131397
  var OPUS_MT_DIRECTION_PATTERN = /^opus-mt-([a-z]{2,3})-([a-z]{2,3})$/i;
131398
+ var OPUS_MT_CT2_SUFFIX_PATTERN = /-(?:ct2|ctranslate2)(?:-[a-z0-9]+)*$/i;
131361
131399
  function inferLocalDirectionalModelLanguagePair(model) {
131362
- const modelName = model?.trim().split("/").pop();
131400
+ const modelName = model?.trim().split("/").pop()?.replace(OPUS_MT_CT2_SUFFIX_PATTERN, "");
131363
131401
  if (!modelName) return null;
131364
131402
  const match = OPUS_MT_DIRECTION_PATTERN.exec(modelName);
131365
131403
  if (!match) return null;
@@ -136415,12 +136453,15 @@ buildSearchIndex(SUPPORTED_TRANSLATION_LANGUAGES.map((language) => ({
136415
136453
  //#endregion
136416
136454
  //#region src/lib/browser-translation.ts
136417
136455
  var browserSupportTableCache = /* @__PURE__ */ new Map();
136456
+ function isRenderableTranslationSegment(segment) {
136457
+ return typeof segment === "object" && segment !== null && !Array.isArray(segment);
136458
+ }
136418
136459
  function createBrowserTranslationExecution() {
136419
136460
  return {
136420
136461
  factory: createBrowserTranslatorFactory(),
136421
136462
  cacheIdentity: {
136422
136463
  engineId: DEFAULT_TRANSLATION_ENGINE_ID,
136423
- translatorContractVersion: 2
136464
+ translatorContractVersion: 3
136424
136465
  }
136425
136466
  };
136426
136467
  }
@@ -136747,7 +136788,7 @@ async function translateMarkdownDocumentProgressively(args, onPatch) {
136747
136788
  onPatch
136748
136789
  })));
136749
136790
  return {
136750
- segments: translatedSegments,
136791
+ segments: normalizeTranslationSegments(translatedSegments),
136751
136792
  displayMode: args.displayMode,
136752
136793
  sourceLanguage: languageDetection.documentLanguage,
136753
136794
  targetLanguage: args.targetLanguage
@@ -136908,7 +136949,7 @@ async function translatePendingJobsBySourceLanguage(input) {
136908
136949
  while (workerPromises.size > 0) await Promise.race(workerPromises);
136909
136950
  }
136910
136951
  function getUnsupportedEngineLanguagePairMessage(input) {
136911
- if (input.engine.cacheIdentity.engineId !== "local") return null;
136952
+ if (!isDirectionalManagedLocalTranslationEngineId(input.engine.cacheIdentity.engineId)) return null;
136912
136953
  const directionCheck = checkLocalDirectionalModelLanguagePair({
136913
136954
  model: input.engine.cacheIdentity.model,
136914
136955
  sourceLanguage: input.sourceLanguage,
@@ -136917,6 +136958,9 @@ function getUnsupportedEngineLanguagePairMessage(input) {
136917
136958
  if (directionCheck.supported) return null;
136918
136959
  return directionCheck.message ?? "Selected local model does not support the detected translation direction.";
136919
136960
  }
136961
+ function normalizeTranslationSegments(segments) {
136962
+ return segments.filter(isRenderableTranslationSegment);
136963
+ }
136920
136964
  function summarizeTranslationLogThroughput(logs) {
136921
136965
  if (logs.length === 0) return 0;
136922
136966
  const totalTokens = logs.reduce((total, log) => total + log.estimatedTokens, 0);
@@ -137469,6 +137513,93 @@ function getErrorMessage(error) {
137469
137513
  return error instanceof Error ? error.message : "Unknown translation error.";
137470
137514
  }
137471
137515
  //#endregion
137516
+ //#region src/lib/document-translation-session-state.ts
137517
+ var DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY = "openspecui:document-translation:mode";
137518
+ var DEFAULT_ACTIVATION = "source";
137519
+ var ACTIVATION_STORAGE_EVENT = "openspecui:document-translation-session-change";
137520
+ function isDocumentTranslationActivation(value) {
137521
+ return value === "source" || value === "translated";
137522
+ }
137523
+ function readDocumentTranslationActivation() {
137524
+ if (typeof window === "undefined") return DEFAULT_ACTIVATION;
137525
+ try {
137526
+ const value = window.sessionStorage.getItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY);
137527
+ return isDocumentTranslationActivation(value) ? value : DEFAULT_ACTIVATION;
137528
+ } catch {
137529
+ return DEFAULT_ACTIVATION;
137530
+ }
137531
+ }
137532
+ function writeDocumentTranslationActivation(value) {
137533
+ if (typeof window === "undefined") return;
137534
+ try {
137535
+ window.sessionStorage.setItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY, value);
137536
+ } catch {
137537
+ return;
137538
+ }
137539
+ window.dispatchEvent(new CustomEvent(ACTIVATION_STORAGE_EVENT, { detail: value }));
137540
+ }
137541
+ function useDocumentTranslationActivation() {
137542
+ const [activation, setActivationState] = (0, import_react.useState)(readDocumentTranslationActivation);
137543
+ (0, import_react.useEffect)(() => {
137544
+ const handleActivationChange = () => {
137545
+ setActivationState(readDocumentTranslationActivation());
137546
+ };
137547
+ window.addEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
137548
+ window.addEventListener("storage", handleActivationChange);
137549
+ return () => {
137550
+ window.removeEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
137551
+ window.removeEventListener("storage", handleActivationChange);
137552
+ };
137553
+ }, []);
137554
+ return {
137555
+ activation,
137556
+ setActivation: (0, import_react.useCallback)((value) => {
137557
+ writeDocumentTranslationActivation(value);
137558
+ setActivationState(value);
137559
+ }, [])
137560
+ };
137561
+ }
137562
+ //#endregion
137563
+ //#region src/lib/resolve-document-translation-config.ts
137564
+ function resolveDocumentTranslationConfig(translationConfig, globalSettings) {
137565
+ if (!translationConfig) return void 0;
137566
+ const local = translationConfig.engines?.local ?? {};
137567
+ const localCt2 = translationConfig.engines?.localCt2 ?? {};
137568
+ const localLlama = translationConfig.engines?.localLlama ?? {};
137569
+ const openai = translationConfig.engines?.openai ?? {};
137570
+ const resolvedLocalModel = local.model ?? globalSettings?.translationEngines.local?.model;
137571
+ const resolvedLocalSelectedGroupId = local.selectedGroupId ?? globalSettings?.translationEngines.local?.selectedGroupId;
137572
+ const resolvedLocalCt2Model = localCt2.model ?? globalSettings?.translationEngines.localCt2?.model;
137573
+ const resolvedLocalCt2SelectedGroupId = localCt2.selectedGroupId ?? globalSettings?.translationEngines.localCt2?.selectedGroupId;
137574
+ const resolvedLocalLlamaModel = localLlama.model ?? globalSettings?.translationEngines.localLlama?.model;
137575
+ const resolvedLocalLlamaSelectedGroupId = localLlama.selectedGroupId ?? globalSettings?.translationEngines.localLlama?.selectedGroupId;
137576
+ const resolvedOpenAIModel = openai.model ?? globalSettings?.translationEngines.openai?.model;
137577
+ return {
137578
+ ...translationConfig,
137579
+ engines: {
137580
+ local: {
137581
+ ...local,
137582
+ ...resolvedLocalModel ? { model: resolvedLocalModel } : {},
137583
+ ...resolvedLocalSelectedGroupId ? { selectedGroupId: resolvedLocalSelectedGroupId } : {}
137584
+ },
137585
+ localCt2: {
137586
+ ...localCt2,
137587
+ ...resolvedLocalCt2Model ? { model: resolvedLocalCt2Model } : {},
137588
+ ...resolvedLocalCt2SelectedGroupId ? { selectedGroupId: resolvedLocalCt2SelectedGroupId } : {}
137589
+ },
137590
+ localLlama: {
137591
+ ...localLlama,
137592
+ ...resolvedLocalLlamaModel ? { model: resolvedLocalLlamaModel } : {},
137593
+ ...resolvedLocalLlamaSelectedGroupId ? { selectedGroupId: resolvedLocalLlamaSelectedGroupId } : {}
137594
+ },
137595
+ openai: {
137596
+ ...openai,
137597
+ ...resolvedOpenAIModel ? { model: resolvedOpenAIModel } : {}
137598
+ }
137599
+ }
137600
+ };
137601
+ }
137602
+ //#endregion
137472
137603
  //#region ../core/src/local-download-profiles.ts
137473
137604
  function selectLocalDownloadGroup(plan, selectedGroupId) {
137474
137605
  if (!plan?.groups?.length) return null;
@@ -137531,25 +137662,37 @@ function projectTranslateServiceStatus(input) {
137531
137662
  };
137532
137663
  }
137533
137664
  }
137534
- if (input.engineId === "local") {
137665
+ if (input.engineLifecycleLoading || input.engineLifecycle !== void 0) {
137666
+ if (input.engineLifecycleLoading || !input.engineLifecycle) return {
137667
+ state: "checking",
137668
+ engineId: input.engineId,
137669
+ message: "Checking translation engine runtime."
137670
+ };
137671
+ if (shouldShowTranslationEngineInstallGate(input.engineLifecycle)) return {
137672
+ state: "unavailable",
137673
+ engineId: input.engineId,
137674
+ message: getTranslationEngineLifecycleMessage(input.engineLifecycle) ?? "Translation engine runtime is not ready."
137675
+ };
137676
+ }
137677
+ if (isManagedLocalTranslationEngineId(input.engineId)) {
137535
137678
  if (!input.localModel?.trim()) return {
137536
137679
  state: "unavailable",
137537
- engineId: "local",
137538
- message: "Select a local model before translating."
137680
+ engineId: input.engineId,
137681
+ message: "Select a model before translating."
137539
137682
  };
137540
137683
  if (input.localAssetLoading || !input.localAsset) return {
137541
137684
  state: "checking",
137542
- engineId: "local",
137685
+ engineId: input.engineId,
137543
137686
  message: "Checking local model files."
137544
137687
  };
137545
137688
  if (isLocalAssetReady(input.localAsset, input.localSelectedGroupId)) return {
137546
137689
  state: "ready",
137547
- engineId: "local",
137690
+ engineId: input.engineId,
137548
137691
  message: "Selected local model files are ready."
137549
137692
  };
137550
137693
  return {
137551
137694
  state: "unavailable",
137552
- engineId: "local",
137695
+ engineId: input.engineId,
137553
137696
  message: "Selected local model files are not installed locally."
137554
137697
  };
137555
137698
  }
@@ -137579,42 +137722,72 @@ async function resolveTranslateServiceState(input) {
137579
137722
  hasSource: input.hasSource,
137580
137723
  engineId: config?.engineId ?? "browser"
137581
137724
  }) });
137582
- if (config.engineId === "local") {
137583
- const model = config.engines.local.model?.trim();
137725
+ let engineLifecycle = null;
137726
+ if (config.engineId !== "browser") {
137727
+ input.onUpdate?.(createTranslateServiceState({ status: projectTranslateServiceStatus({
137728
+ enabled: config.enabled,
137729
+ hasSource: input.hasSource,
137730
+ engineId: config.engineId,
137731
+ engineLifecycleLoading: true
137732
+ }) }));
137733
+ try {
137734
+ engineLifecycle = await trpcClient.translationEngines.getLifecycle.query({ engineId: config.engineId });
137735
+ } catch (lifecycleError) {
137736
+ return createTranslateServiceState({ status: {
137737
+ state: "unavailable",
137738
+ engineId: config.engineId,
137739
+ message: lifecycleError instanceof Error ? lifecycleError.message : "Unable to check translation engine runtime."
137740
+ } });
137741
+ }
137742
+ if (shouldShowTranslationEngineInstallGate(engineLifecycle)) return createTranslateServiceState({ status: projectTranslateServiceStatus({
137743
+ enabled: config.enabled,
137744
+ hasSource: input.hasSource,
137745
+ engineId: config.engineId,
137746
+ engineLifecycle
137747
+ }) });
137748
+ }
137749
+ if (isManagedLocalTranslationEngineId(config.engineId)) {
137750
+ const localEngineConfig = getManagedLocalEngineConfig(config);
137751
+ const model = localEngineConfig.model?.trim();
137584
137752
  if (!model) return emitTranslateServiceState(input.onUpdate, { status: projectTranslateServiceStatus({
137585
137753
  enabled: config.enabled,
137586
137754
  hasSource: input.hasSource,
137587
- engineId: "local",
137755
+ engineId: config.engineId,
137756
+ engineLifecycle,
137588
137757
  localModel: model,
137589
- localSelectedGroupId: config.engines.local.selectedGroupId
137758
+ localSelectedGroupId: localEngineConfig.selectedGroupId
137590
137759
  }) });
137591
- const directionCheck = checkLocalDirectionalModelLanguagePair({
137592
- model,
137593
- targetLanguage: config.targetLanguage
137594
- });
137595
- if (!directionCheck.supported) return emitTranslateServiceState(input.onUpdate, { status: {
137596
- state: "unavailable",
137597
- engineId: "local",
137598
- message: directionCheck.message ?? "Selected local model does not support the configured target language."
137599
- } });
137760
+ if (isDirectionalManagedLocalTranslationEngineId(config.engineId)) {
137761
+ const directionCheck = checkLocalDirectionalModelLanguagePair({
137762
+ model,
137763
+ targetLanguage: config.targetLanguage
137764
+ });
137765
+ if (!directionCheck.supported) return emitTranslateServiceState(input.onUpdate, { status: {
137766
+ state: "unavailable",
137767
+ engineId: config.engineId,
137768
+ message: directionCheck.message ?? "Selected local model does not support the configured target language."
137769
+ } });
137770
+ }
137600
137771
  input.onUpdate?.(createTranslateServiceState({ status: projectTranslateServiceStatus({
137601
137772
  enabled: config.enabled,
137602
137773
  hasSource: input.hasSource,
137603
- engineId: "local",
137774
+ engineId: config.engineId,
137775
+ engineLifecycle,
137604
137776
  localModel: model,
137605
- localSelectedGroupId: config.engines.local.selectedGroupId,
137777
+ localSelectedGroupId: localEngineConfig.selectedGroupId,
137606
137778
  localAssetLoading: true
137607
137779
  }) }));
137608
137780
  try {
137609
- const panelState = await trpcClient.localModels.panelState.query({
137781
+ const panelState = await queryManagedLocalPanelState(config.engineId, {
137610
137782
  modelId: model,
137611
- selectedGroupId: config.engines.local.selectedGroupId
137783
+ selectedGroupId: localEngineConfig.selectedGroupId
137612
137784
  });
137613
- const selectedGroupId = panelState.selectedGroupId ?? config.engines.local.selectedGroupId;
137785
+ const selectedGroupId = panelState.selectedGroupId ?? localEngineConfig.selectedGroupId;
137614
137786
  return createTranslateServiceState({ status: projectTranslateServiceStatus({
137615
137787
  enabled: config.enabled,
137616
137788
  hasSource: input.hasSource,
137617
- engineId: "local",
137789
+ engineId: config.engineId,
137790
+ engineLifecycle,
137618
137791
  localModel: model,
137619
137792
  localSelectedGroupId: selectedGroupId,
137620
137793
  localAsset: panelState.asset
@@ -137622,7 +137795,7 @@ async function resolveTranslateServiceState(input) {
137622
137795
  } catch (assetError) {
137623
137796
  return createTranslateServiceState({ status: {
137624
137797
  state: "unavailable",
137625
- engineId: "local",
137798
+ engineId: config.engineId,
137626
137799
  message: assetError instanceof Error ? assetError.message : "Unable to check local model files."
137627
137800
  } });
137628
137801
  }
@@ -137630,7 +137803,8 @@ async function resolveTranslateServiceState(input) {
137630
137803
  if (config.engineId === "openai") return emitTranslateServiceState(input.onUpdate, { status: projectTranslateServiceStatus({
137631
137804
  enabled: config.enabled,
137632
137805
  hasSource: input.hasSource,
137633
- engineId: "openai"
137806
+ engineId: "openai",
137807
+ engineLifecycle
137634
137808
  }) });
137635
137809
  const cachedTable = getBrowserSupportTableState(config.targetLanguage);
137636
137810
  if (cachedTable) return emitTranslateServiceState(input.onUpdate, {
@@ -137732,14 +137906,14 @@ function prepareTranslateServiceRun(input) {
137732
137906
  }
137733
137907
  function createTranslationEngineExecution(config) {
137734
137908
  if (config.engineId === "browser" || isStaticMode()) return createBrowserTranslationExecution();
137735
- const model = config.engineId === "openai" ? config.engines.openai.model : config.engines.local.model;
137909
+ const model = config.engineId === "openai" ? config.engines.openai.model : getManagedLocalEngineConfig(config).model;
137736
137910
  return {
137737
- factory: new TrpcTranslatorFactory(config.engineId, model, config.engineId === "local" ? config.engines.local.selectedGroupId : void 0),
137911
+ factory: new TrpcTranslatorFactory(config.engineId, model, isManagedLocalTranslationEngineId(config.engineId) ? getManagedLocalEngineConfig(config).selectedGroupId : void 0),
137738
137912
  cacheIdentity: {
137739
137913
  engineId: config.engineId,
137740
137914
  model,
137741
- selectedGroupId: config.engineId === "local" ? config.engines.local.selectedGroupId : void 0,
137742
- translatorContractVersion: 2
137915
+ selectedGroupId: isManagedLocalTranslationEngineId(config.engineId) ? getManagedLocalEngineConfig(config).selectedGroupId : void 0,
137916
+ translatorContractVersion: 3
137743
137917
  }
137744
137918
  };
137745
137919
  }
@@ -137755,10 +137929,25 @@ var TrpcTranslatorFactory = class {
137755
137929
  sourceLanguage: options.sourceLanguage,
137756
137930
  targetLanguage: options.targetLanguage,
137757
137931
  model: options.model ?? this.model,
137758
- selectedGroupId: this.engineId === "local" ? this.selectedGroupId : void 0
137932
+ selectedGroupId: isManagedLocalTranslationEngineId(this.engineId) ? this.selectedGroupId : void 0
137759
137933
  });
137760
137934
  }
137761
137935
  };
137936
+ function getManagedLocalEngineConfig(config) {
137937
+ return config.engineId === "local-ct2" ? {
137938
+ model: config.engines.localCt2.model,
137939
+ selectedGroupId: config.engines.localCt2.selectedGroupId
137940
+ } : config.engineId === "local-llama" ? {
137941
+ model: config.engines.localLlama.model,
137942
+ selectedGroupId: config.engines.localLlama.selectedGroupId
137943
+ } : {
137944
+ model: config.engines.local.model,
137945
+ selectedGroupId: config.engines.local.selectedGroupId
137946
+ };
137947
+ }
137948
+ async function queryManagedLocalPanelState(engineId, input) {
137949
+ return engineId === "local" ? trpcClient.localModels.panelState.query(input) : engineId === "local-ct2" ? trpcClient.localCt2Models.panelState.query(input) : trpcClient.localLlamaModels.panelState.query(input);
137950
+ }
137762
137951
  var TrpcTranslator = class {
137763
137952
  constructor(options) {
137764
137953
  this.options = options;
@@ -137832,11 +138021,13 @@ function useDocumentTranslation(markdown, config) {
137832
138021
  const abortRef = (0, import_react.useRef)(null);
137833
138022
  const generationRef = (0, import_react.useRef)(0);
137834
138023
  const latestStartRef = (0, import_react.useRef)(null);
138024
+ const segmentPatchMapRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
137835
138025
  const { activation } = useDocumentTranslationActivation();
137836
138026
  const cancel = (0, import_react.useCallback)(() => {
137837
138027
  generationRef.current += 1;
137838
138028
  abortRef.current?.abort();
137839
138029
  abortRef.current = null;
138030
+ segmentPatchMapRef.current.clear();
137840
138031
  setStatus("source");
137841
138032
  setResult(null);
137842
138033
  setError(null);
@@ -137845,6 +138036,7 @@ function useDocumentTranslation(markdown, config) {
137845
138036
  generationRef.current += 1;
137846
138037
  abortRef.current?.abort();
137847
138038
  abortRef.current = null;
138039
+ segmentPatchMapRef.current.clear();
137848
138040
  setStatus("source");
137849
138041
  setResult(null);
137850
138042
  setError(null);
@@ -137854,6 +138046,7 @@ function useDocumentTranslation(markdown, config) {
137854
138046
  generationRef.current += 1;
137855
138047
  setCapability(null);
137856
138048
  setBrowserSupportTable(null);
138049
+ segmentPatchMapRef.current.clear();
137857
138050
  setResult(null);
137858
138051
  setStatus("source");
137859
138052
  setError(null);
@@ -137864,6 +138057,10 @@ function useDocumentTranslation(markdown, config) {
137864
138057
  config?.engineId,
137865
138058
  config?.engines.local.model,
137866
138059
  config?.engines.local.selectedGroupId,
138060
+ config?.engines.localCt2.model,
138061
+ config?.engines.localCt2.selectedGroupId,
138062
+ config?.engines.localLlama.model,
138063
+ config?.engines.localLlama.selectedGroupId,
137867
138064
  config?.engines.openai.model,
137868
138065
  config?.targetLanguage
137869
138066
  ]);
@@ -137904,6 +138101,10 @@ function useDocumentTranslation(markdown, config) {
137904
138101
  config?.engineId,
137905
138102
  config?.engines.local.model,
137906
138103
  config?.engines.local.selectedGroupId,
138104
+ config?.engines.localCt2.model,
138105
+ config?.engines.localCt2.selectedGroupId,
138106
+ config?.engines.localLlama.model,
138107
+ config?.engines.localLlama.selectedGroupId,
137907
138108
  config?.targetLanguage,
137908
138109
  markdown.length
137909
138110
  ]);
@@ -137914,6 +138115,7 @@ function useDocumentTranslation(markdown, config) {
137914
138115
  const generationId = generationRef.current + 1;
137915
138116
  generationRef.current = generationId;
137916
138117
  abortRef.current = controller;
138118
+ segmentPatchMapRef.current.clear();
137917
138119
  setError(null);
137918
138120
  setStatus("initializing");
137919
138121
  try {
@@ -137958,11 +138160,11 @@ function useDocumentTranslation(markdown, config) {
137958
138160
  setResult((current) => applyDocumentTranslationPatch(current, patch, {
137959
138161
  displayMode: config.displayMode,
137960
138162
  targetLanguage: config.targetLanguage
137961
- }));
138163
+ }, segmentPatchMapRef.current));
137962
138164
  });
137963
138165
  if (controller.signal.aborted || abortRef.current !== controller || generationRef.current !== generationId) return;
137964
138166
  const documentFailure = getDocumentTranslationFailureMessage(nextResult);
137965
- setResult(nextResult);
138167
+ setResult(normalizeDocumentTranslationResult(nextResult));
137966
138168
  if (documentFailure) {
137967
138169
  setError(documentFailure);
137968
138170
  setStatus("error");
@@ -137986,6 +138188,10 @@ function useDocumentTranslation(markdown, config) {
137986
138188
  config?.engines.openai.model,
137987
138189
  config?.engines.local.model,
137988
138190
  config?.engines.local.selectedGroupId,
138191
+ config?.engines.localCt2.model,
138192
+ config?.engines.localCt2.selectedGroupId,
138193
+ config?.engines.localLlama.model,
138194
+ config?.engines.localLlama.selectedGroupId,
137989
138195
  markdown,
137990
138196
  serviceStatus
137991
138197
  ]);
@@ -138015,22 +138221,33 @@ function useDocumentTranslation(markdown, config) {
138015
138221
  reset
138016
138222
  };
138017
138223
  }
138224
+ function isDocumentTranslationSegment(segment) {
138225
+ return typeof segment === "object" && segment !== null && !Array.isArray(segment);
138226
+ }
138018
138227
  function getDocumentTranslationFailureMessage(result) {
138019
- const segments = (Array.isArray(result.segments) ? result.segments : []).filter((segment) => segment !== void 0);
138228
+ const segments = (Array.isArray(result.segments) ? result.segments : []).filter(isDocumentTranslationSegment);
138020
138229
  if (segments.length === 0) return null;
138021
138230
  if (segments.some((segment) => segment.status !== "error" && typeof segment.target === "string")) return null;
138022
138231
  const errors = segments.map((segment) => segment.status === "error" ? segment.error : void 0).filter((message) => typeof message === "string" && message.length > 0);
138023
138232
  if (errors.length === 0) return null;
138024
138233
  return errors[0] ?? "Translation failed.";
138025
138234
  }
138026
- function applyDocumentTranslationPatch(current, patch, fallback) {
138027
- const segments = [...current?.segments ?? []];
138028
- segments[patch.segmentIndex] = patch.segment;
138029
- return {
138235
+ function applyDocumentTranslationPatch(current, patch, fallback, patchMap) {
138236
+ patchMap.set(patch.segmentIndex, patch.segment);
138237
+ return buildPatchedDocumentTranslationResult(current, fallback, patchMap);
138238
+ }
138239
+ function buildPatchedDocumentTranslationResult(current, fallback, patchMap) {
138240
+ return normalizeDocumentTranslationResult({
138030
138241
  displayMode: current?.displayMode ?? fallback.displayMode,
138031
138242
  sourceLanguage: current?.sourceLanguage,
138032
138243
  targetLanguage: current?.targetLanguage ?? fallback.targetLanguage,
138033
- segments
138244
+ segments: [...patchMap.entries()].sort((left, right) => left[0] - right[0]).map(([, segment]) => segment)
138245
+ });
138246
+ }
138247
+ function normalizeDocumentTranslationResult(result) {
138248
+ return {
138249
+ ...result,
138250
+ segments: (Array.isArray(result.segments) ? result.segments : []).filter(isDocumentTranslationSegment)
138034
138251
  };
138035
138252
  }
138036
138253
  //#endregion
@@ -148832,6 +149049,8 @@ function useDocumentTranslationRenderPlugin({ markdown, translationConfig }) {
148832
149049
  resolvedTranslationConfig?.engineId,
148833
149050
  resolvedTranslationConfig?.engines.local.model ?? "no-local-model",
148834
149051
  resolvedTranslationConfig?.engines.local.selectedGroupId ?? "no-local-group",
149052
+ resolvedTranslationConfig?.engines.localCt2.model ?? "no-local-ct2-model",
149053
+ resolvedTranslationConfig?.engines.localCt2.selectedGroupId ?? "no-local-ct2-group",
148835
149054
  session.capability?.availability ?? "unknown",
148836
149055
  session.capability?.message ?? "no-message",
148837
149056
  session.serviceStatus.state,
@@ -148882,7 +149101,7 @@ function hashString(value) {
148882
149101
  }
148883
149102
  function createTranslationProjection(result) {
148884
149103
  if (!result) return { blockAnnotations: [] };
148885
- const segments = Array.isArray(result.segments) ? result.segments : [];
149104
+ const segments = getRenderableTranslationSegments(result);
148886
149105
  const segmentByOffset = new Map(segments.filter((segment) => segment.target).map((segment) => [segment.sourceStartOffset, segment]));
148887
149106
  return {
148888
149107
  headingProcessor: {
@@ -148926,6 +149145,9 @@ function createTranslationProjection(result) {
148926
149145
  }))
148927
149146
  };
148928
149147
  }
149148
+ function getRenderableTranslationSegments(result) {
149149
+ return (Array.isArray(result.segments) ? result.segments : []).filter(isRenderableTranslationSegment);
149150
+ }
148929
149151
  function createTranslatedHeadingTransform(input, segment, displayMode) {
148930
149152
  const projectedTarget = segment.target ?? "";
148931
149153
  const openSpecHeading = createTranslatedOpenSpecHeadingProjection(input, segment, displayMode);