@deepseek-ai/dsh-client-ui-conversation 0.1.2-alpha.2 → 0.1.2-alpha.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.
- package/README.i18n.yaml +2 -2
- package/README.md +6 -2
- package/README.zh.md +6 -2
- package/lib/client.js +402 -214
- package/lib/types/client/contract/conversation.d.ts +1 -1
- package/lib/types/client/contract/slots.d.ts +4 -0
- package/lib/types/client/conversation/assembler.d.ts +20 -4
- package/lib/types/client/conversation/assembly.d.ts +7 -0
- package/lib/types/client/image-labels.d.ts +1 -1
- package/lib/types/client/locales.d.ts +2 -2
- package/lib/types/client/queue/QueueDock.d.ts +4 -1
- package/lib/types/client/skeleton/ConversationSession.d.ts +2 -2
- package/lib/types/client/stores.d.ts +7 -0
- package/lib/types/client/view-selection.d.ts +9 -0
- package/package.json +30 -30
package/lib/client.js
CHANGED
|
@@ -568,12 +568,15 @@ window.__ModuleLoader__.load({
|
|
|
568
568
|
contexts = /* @__PURE__ */ new Map();
|
|
569
569
|
contextsByKind = /* @__PURE__ */ new Map();
|
|
570
570
|
contextsBySeq = /* @__PURE__ */ new Map();
|
|
571
|
+
contextsByTarget = /* @__PURE__ */ new Map();
|
|
571
572
|
inputs = /* @__PURE__ */ new Map();
|
|
572
573
|
locationIndex = new ConversationLocationIndex();
|
|
573
574
|
dirty = /* @__PURE__ */ new Set();
|
|
575
|
+
dirtyByTarget = /* @__PURE__ */ new Map();
|
|
574
576
|
revised = /* @__PURE__ */ new Set();
|
|
575
577
|
dependents = /* @__PURE__ */ new Map();
|
|
576
578
|
views = /* @__PURE__ */ new Map();
|
|
579
|
+
activeTargets = /* @__PURE__ */ new Set();
|
|
577
580
|
hasMore = false;
|
|
578
581
|
replacePending = true;
|
|
579
582
|
timelineDirty = true;
|
|
@@ -596,8 +599,10 @@ window.__ModuleLoader__.load({
|
|
|
596
599
|
this.contexts.clear();
|
|
597
600
|
this.contextsByKind.clear();
|
|
598
601
|
this.contextsBySeq.clear();
|
|
602
|
+
this.contextsByTarget.clear();
|
|
599
603
|
this.inputs.clear();
|
|
600
604
|
this.dirty.clear();
|
|
605
|
+
this.dirtyByTarget.clear();
|
|
601
606
|
this.revised.clear();
|
|
602
607
|
this.dependents.clear();
|
|
603
608
|
this.hasMore = hasMore;
|
|
@@ -608,7 +613,7 @@ window.__ModuleLoader__.load({
|
|
|
608
613
|
for (const entry of sorted) this.matchInput(entry);
|
|
609
614
|
this.replayDependencies();
|
|
610
615
|
this.revised.clear();
|
|
611
|
-
for (const context of this.contexts.values()) this.
|
|
616
|
+
for (const context of this.contexts.values()) this.markDirty(context);
|
|
612
617
|
this.replacePending = true;
|
|
613
618
|
return "immediate";
|
|
614
619
|
}
|
|
@@ -673,60 +678,71 @@ window.__ModuleLoader__.load({
|
|
|
673
678
|
return this.replaceWindow(this.sortedInputs(), this.hasMore);
|
|
674
679
|
}
|
|
675
680
|
/**
|
|
676
|
-
* Materialize dirty Contexts and advance every
|
|
681
|
+
* Materialize dirty Contexts and advance every active view builder.
|
|
677
682
|
* @returns whether any view snapshot was rebuilt or incrementally applied.
|
|
678
683
|
*/
|
|
679
684
|
flush() {
|
|
680
685
|
if (!this.replacePending && this.dirty.size === 0 && !this.timelineDirty) return false;
|
|
681
686
|
if (this.replacePending) {
|
|
682
687
|
this.replaceLocationData();
|
|
683
|
-
|
|
684
|
-
for (const target of this.
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
});
|
|
688
|
+
let published = false;
|
|
689
|
+
for (const target of this.activeTargets) {
|
|
690
|
+
const view = this.views.get(target);
|
|
691
|
+
if (view === void 0) continue;
|
|
692
|
+
const builder = view.builder ?? view.definition.create();
|
|
693
|
+
view.builder = builder;
|
|
694
|
+
view.snapshot = builder.replace({
|
|
695
|
+
nodes: this.buildTargetNodes(target, this.contextsByTarget.get(target)),
|
|
696
|
+
timeline: this.locationIndex.snapshot()
|
|
697
|
+
});
|
|
698
|
+
published = true;
|
|
699
|
+
}
|
|
696
700
|
this.replacePending = false;
|
|
697
701
|
this.dirty.clear();
|
|
702
|
+
this.dirtyByTarget.clear();
|
|
698
703
|
this.timelineDirty = false;
|
|
699
|
-
return
|
|
704
|
+
return published;
|
|
700
705
|
}
|
|
701
|
-
|
|
702
|
-
for (const target of this.views.keys()) upsertsByTarget.set(target, []);
|
|
706
|
+
let published = false;
|
|
703
707
|
if (this.applyDirtyLocationData()) this.timelineDirty = true;
|
|
704
|
-
for (const context of this.dirty) {
|
|
705
|
-
const target = context.definition.target;
|
|
706
|
-
if (target === void 0 || !this.views.has(target)) continue;
|
|
707
|
-
const previous = context.current.get(target) ?? null;
|
|
708
|
-
const node = this.buildNode(context, target);
|
|
709
|
-
if (node === null && previous !== null) throw new Error(`conversation Definition "${context.kind}" withdrew materialized target "${target}"; return the same key with hidden visibility instead`);
|
|
710
|
-
context.current.set(target, node);
|
|
711
|
-
if (node !== null) upsertsByTarget.get(target)?.push(node);
|
|
712
|
-
}
|
|
713
|
-
this.dirty.clear();
|
|
714
708
|
const timelineDirty = this.timelineDirty;
|
|
715
|
-
this.
|
|
716
|
-
|
|
717
|
-
|
|
709
|
+
for (const target of this.activeTargets) {
|
|
710
|
+
const view = this.views.get(target);
|
|
711
|
+
if (view === void 0) continue;
|
|
712
|
+
const builder = view.builder;
|
|
713
|
+
if (builder === void 0) continue;
|
|
714
|
+
const upserts = this.buildTargetUpserts(target, this.dirtyByTarget.get(target));
|
|
718
715
|
if (upserts.length === 0 && !timelineDirty) continue;
|
|
719
|
-
view.snapshot =
|
|
716
|
+
view.snapshot = builder.apply({
|
|
720
717
|
upserts,
|
|
721
718
|
timeline: this.locationIndex.snapshot()
|
|
722
719
|
});
|
|
720
|
+
published = true;
|
|
723
721
|
}
|
|
722
|
+
this.dirty.clear();
|
|
723
|
+
this.dirtyByTarget.clear();
|
|
724
|
+
this.timelineDirty = false;
|
|
725
|
+
return published;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Add one target to the monotonic active set and materialize its current snapshot.
|
|
729
|
+
* Pending Context work is flushed before the first complete replacement.
|
|
730
|
+
* @param target - registered or subsequently registered view target.
|
|
731
|
+
* @returns whether any active target snapshot changed.
|
|
732
|
+
*/
|
|
733
|
+
activateTarget(target) {
|
|
734
|
+
const view = this.views.get(target);
|
|
735
|
+
if (this.activeTargets.has(target)) return false;
|
|
736
|
+
const published = this.flush();
|
|
737
|
+
this.activeTargets.add(target);
|
|
738
|
+
if (view === void 0) return published;
|
|
739
|
+
this.replaceView(view);
|
|
724
740
|
return true;
|
|
725
741
|
}
|
|
726
742
|
/**
|
|
727
743
|
* Read the latest snapshot of a registered target.
|
|
728
744
|
* @param target - registered view target.
|
|
729
|
-
* @returns target snapshot, or undefined
|
|
745
|
+
* @returns target snapshot, or undefined before registration or activation.
|
|
730
746
|
*/
|
|
731
747
|
snapshot(target) {
|
|
732
748
|
return this.views.get(target)?.snapshot;
|
|
@@ -736,11 +752,15 @@ window.__ModuleLoader__.load({
|
|
|
736
752
|
}
|
|
737
753
|
/**
|
|
738
754
|
* Read targets whose owners classify their latest snapshot as visible activity.
|
|
739
|
-
* @returns
|
|
755
|
+
* @returns target ids contributing visible activity.
|
|
740
756
|
*/
|
|
741
|
-
|
|
757
|
+
activityTargets() {
|
|
742
758
|
const active = /* @__PURE__ */ new Set();
|
|
743
|
-
for (const
|
|
759
|
+
for (const target of this.activeTargets) {
|
|
760
|
+
const view = this.views.get(target);
|
|
761
|
+
if (view === void 0) continue;
|
|
762
|
+
if (view.isActive?.(view.snapshot) === true) active.add(view.target);
|
|
763
|
+
}
|
|
744
764
|
return active;
|
|
745
765
|
}
|
|
746
766
|
sortedInputs() {
|
|
@@ -781,27 +801,30 @@ window.__ModuleLoader__.load({
|
|
|
781
801
|
}
|
|
782
802
|
return publication;
|
|
783
803
|
}
|
|
804
|
+
createContext(definition, id, key) {
|
|
805
|
+
const context = {
|
|
806
|
+
key,
|
|
807
|
+
kind: definition.kind,
|
|
808
|
+
id,
|
|
809
|
+
definition,
|
|
810
|
+
startSeq: void 0,
|
|
811
|
+
start: void 0,
|
|
812
|
+
matches: [],
|
|
813
|
+
state: void 0,
|
|
814
|
+
revision: 0,
|
|
815
|
+
current: /* @__PURE__ */ new Map(),
|
|
816
|
+
locationData: emptyLocationData(),
|
|
817
|
+
dependencies: /* @__PURE__ */ new Map()
|
|
818
|
+
};
|
|
819
|
+
this.contexts.set(key, context);
|
|
820
|
+
this.indexTargetContext(context);
|
|
821
|
+
return context;
|
|
822
|
+
}
|
|
784
823
|
acceptMatch(definition, id, role, input) {
|
|
785
824
|
const key = conversationContextKey(definition.kind, id);
|
|
786
825
|
let context = this.contexts.get(key);
|
|
787
826
|
if (role === "start" && context?.start !== void 0) throw new Error(`conversation Context ${key} received more than one start Match`);
|
|
788
|
-
|
|
789
|
-
context = {
|
|
790
|
-
key,
|
|
791
|
-
kind: definition.kind,
|
|
792
|
-
id,
|
|
793
|
-
definition,
|
|
794
|
-
startSeq: void 0,
|
|
795
|
-
start: void 0,
|
|
796
|
-
matches: [],
|
|
797
|
-
state: void 0,
|
|
798
|
-
revision: 0,
|
|
799
|
-
current: /* @__PURE__ */ new Map(),
|
|
800
|
-
locationData: emptyLocationData(),
|
|
801
|
-
dependencies: /* @__PURE__ */ new Map()
|
|
802
|
-
};
|
|
803
|
-
this.contexts.set(key, context);
|
|
804
|
-
}
|
|
827
|
+
context ??= this.createContext(definition, id, key);
|
|
805
828
|
const match = conversationMatch(key, input, role, this.locationIndex.locationOf(input.event));
|
|
806
829
|
const previous = context.matches.at(-1);
|
|
807
830
|
if (previous !== void 0 && previous.event.seq >= input.event.seq) throw new Error(`conversation Context ${key} received non-appended Match ${input.event.seq}`);
|
|
@@ -822,7 +845,7 @@ window.__ModuleLoader__.load({
|
|
|
822
845
|
context.revision++;
|
|
823
846
|
this.revised.add(context);
|
|
824
847
|
}
|
|
825
|
-
this.
|
|
848
|
+
this.markDirty(context);
|
|
826
849
|
return definition.publication?.(match) ?? "immediate";
|
|
827
850
|
}
|
|
828
851
|
applyPendingMatches(pending, affected) {
|
|
@@ -831,23 +854,7 @@ window.__ModuleLoader__.load({
|
|
|
831
854
|
const first = entries[0];
|
|
832
855
|
if (first === void 0) continue;
|
|
833
856
|
let context = this.contexts.get(key);
|
|
834
|
-
|
|
835
|
-
context = {
|
|
836
|
-
key,
|
|
837
|
-
kind: first.definition.kind,
|
|
838
|
-
id: first.id,
|
|
839
|
-
definition: first.definition,
|
|
840
|
-
startSeq: void 0,
|
|
841
|
-
start: void 0,
|
|
842
|
-
matches: [],
|
|
843
|
-
state: void 0,
|
|
844
|
-
revision: 0,
|
|
845
|
-
current: /* @__PURE__ */ new Map(),
|
|
846
|
-
locationData: emptyLocationData(),
|
|
847
|
-
dependencies: /* @__PURE__ */ new Map()
|
|
848
|
-
};
|
|
849
|
-
this.contexts.set(key, context);
|
|
850
|
-
}
|
|
857
|
+
context ??= this.createContext(first.definition, first.id, key);
|
|
851
858
|
let discoveredStart;
|
|
852
859
|
const additions = entries.map((entry) => {
|
|
853
860
|
if (entry.definition !== context.definition || entry.id !== context.id) throw new Error(`conversation Context ${key} received inconsistent Definition identity`);
|
|
@@ -870,7 +877,7 @@ window.__ModuleLoader__.load({
|
|
|
870
877
|
}
|
|
871
878
|
if (context.start !== void 0 && context.matches[0] !== context.start) throw new Error(`conversation Context ${context.key} received an update before its start Match`);
|
|
872
879
|
affected.add(context);
|
|
873
|
-
this.
|
|
880
|
+
this.markDirty(context);
|
|
874
881
|
}
|
|
875
882
|
for (const [kind, contexts] of startsByKind) this.indexStartedContexts(kind, contexts);
|
|
876
883
|
}
|
|
@@ -879,7 +886,7 @@ window.__ModuleLoader__.load({
|
|
|
879
886
|
for (const context of ordered) {
|
|
880
887
|
if (context.start === void 0) {
|
|
881
888
|
context.state = void 0;
|
|
882
|
-
this.
|
|
889
|
+
this.markDirty(context);
|
|
883
890
|
continue;
|
|
884
891
|
}
|
|
885
892
|
this.replayContext(context);
|
|
@@ -905,7 +912,22 @@ window.__ModuleLoader__.load({
|
|
|
905
912
|
}
|
|
906
913
|
context.revision++;
|
|
907
914
|
this.revised.add(context);
|
|
915
|
+
this.markDirty(context);
|
|
916
|
+
}
|
|
917
|
+
indexTargetContext(context) {
|
|
918
|
+
const target = context.definition.target;
|
|
919
|
+
if (target === void 0) return;
|
|
920
|
+
const contexts = this.contextsByTarget.get(target) ?? /* @__PURE__ */ new Set();
|
|
921
|
+
contexts.add(context);
|
|
922
|
+
this.contextsByTarget.set(target, contexts);
|
|
923
|
+
}
|
|
924
|
+
markDirty(context) {
|
|
908
925
|
this.dirty.add(context);
|
|
926
|
+
const target = context.definition.target;
|
|
927
|
+
if (target === void 0 || !this.activeTargets.has(target)) return;
|
|
928
|
+
const contexts = this.dirtyByTarget.get(target) ?? /* @__PURE__ */ new Set();
|
|
929
|
+
contexts.add(context);
|
|
930
|
+
this.dirtyByTarget.set(target, contexts);
|
|
909
931
|
}
|
|
910
932
|
replaceDependencies(context, dependencies) {
|
|
911
933
|
for (const dependency of context.dependencies.values()) {
|
|
@@ -1053,6 +1075,34 @@ window.__ModuleLoader__.load({
|
|
|
1053
1075
|
if (node.target !== target) throw new Error(`conversation Definition "${context.kind}" returned target "${node.target}" while building "${target}"`);
|
|
1054
1076
|
return node;
|
|
1055
1077
|
}
|
|
1078
|
+
replaceView(view) {
|
|
1079
|
+
const builder = view.builder ?? view.definition.create();
|
|
1080
|
+
view.builder = builder;
|
|
1081
|
+
view.snapshot = builder.replace({
|
|
1082
|
+
nodes: this.buildTargetNodes(view.target, this.contextsByTarget.get(view.target)),
|
|
1083
|
+
timeline: this.locationIndex.snapshot()
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
buildTargetNodes(target, contexts) {
|
|
1087
|
+
const nodes = [];
|
|
1088
|
+
for (const context of contexts ?? []) {
|
|
1089
|
+
const node = this.buildNode(context, target);
|
|
1090
|
+
context.current.set(target, node);
|
|
1091
|
+
if (node !== null) nodes.push(node);
|
|
1092
|
+
}
|
|
1093
|
+
return nodes;
|
|
1094
|
+
}
|
|
1095
|
+
buildTargetUpserts(target, contexts) {
|
|
1096
|
+
const upserts = [];
|
|
1097
|
+
for (const context of contexts ?? []) {
|
|
1098
|
+
const previous = context.current.get(target) ?? null;
|
|
1099
|
+
const node = this.buildNode(context, target);
|
|
1100
|
+
if (node === null && previous !== null) throw new Error(`conversation Definition "${context.kind}" withdrew materialized target "${target}"; return the same key with hidden visibility instead`);
|
|
1101
|
+
context.current.set(target, node);
|
|
1102
|
+
if (node !== null) upserts.push(node);
|
|
1103
|
+
}
|
|
1104
|
+
return upserts;
|
|
1105
|
+
}
|
|
1056
1106
|
buildLocationData(context, scope) {
|
|
1057
1107
|
if (context.definition.buildLocationData === void 0) return null;
|
|
1058
1108
|
const data = context.definition.buildLocationData(contextSnapshot(context), scope);
|
|
@@ -1098,13 +1148,14 @@ window.__ModuleLoader__.load({
|
|
|
1098
1148
|
resetViewBuilders() {
|
|
1099
1149
|
this.views.clear();
|
|
1100
1150
|
for (const definition of this.viewDefinitions.entries()) {
|
|
1101
|
-
const
|
|
1102
|
-
this.views.set(definition.target, {
|
|
1151
|
+
const view = {
|
|
1103
1152
|
target: definition.target,
|
|
1104
|
-
|
|
1153
|
+
definition,
|
|
1105
1154
|
isActive: definition.isActive === void 0 ? void 0 : (snapshot) => definition.isActive?.(snapshot) === true,
|
|
1106
|
-
|
|
1107
|
-
|
|
1155
|
+
builder: void 0,
|
|
1156
|
+
snapshot: void 0
|
|
1157
|
+
};
|
|
1158
|
+
this.views.set(definition.target, view);
|
|
1108
1159
|
}
|
|
1109
1160
|
this.replacePending = true;
|
|
1110
1161
|
}
|
|
@@ -1438,13 +1489,18 @@ window.__ModuleLoader__.load({
|
|
|
1438
1489
|
source = {
|
|
1439
1490
|
getSnapshot: () => views.get(target),
|
|
1440
1491
|
subscribe: (listener) => {
|
|
1441
|
-
|
|
1492
|
+
const unsubscribe = this.snapshot.subscribe(listener);
|
|
1493
|
+
this.activate(target);
|
|
1494
|
+
return unsubscribe;
|
|
1442
1495
|
}
|
|
1443
1496
|
};
|
|
1444
1497
|
this.targetSources.set(target, source);
|
|
1445
1498
|
}
|
|
1446
1499
|
return source;
|
|
1447
1500
|
}
|
|
1501
|
+
activate(target) {
|
|
1502
|
+
if (this.assembler.activateTarget(target)) this.snapshot.set(this.currentSnapshot());
|
|
1503
|
+
}
|
|
1448
1504
|
rebuild() {
|
|
1449
1505
|
this.publish(this.assembler.rebuildRegistry());
|
|
1450
1506
|
}
|
|
@@ -1496,7 +1552,7 @@ window.__ModuleLoader__.load({
|
|
|
1496
1552
|
currentSnapshot() {
|
|
1497
1553
|
return {
|
|
1498
1554
|
views: this.viewStore,
|
|
1499
|
-
activeTargets: this.assembler.
|
|
1555
|
+
activeTargets: this.assembler.activityTargets()
|
|
1500
1556
|
};
|
|
1501
1557
|
}
|
|
1502
1558
|
};
|
|
@@ -1622,6 +1678,7 @@ window.__ModuleLoader__.load({
|
|
|
1622
1678
|
//#endregion
|
|
1623
1679
|
//#region lib/types/client/stores.js
|
|
1624
1680
|
/** Per-session Conversation store shared by the shell body and header. */
|
|
1681
|
+
const CONVERSATION_STORE_KEY = "dsh.conversation";
|
|
1625
1682
|
/**
|
|
1626
1683
|
* Declare per-session draft persistence and View selection.
|
|
1627
1684
|
* @returns the store handle.
|
|
@@ -1633,7 +1690,7 @@ window.__ModuleLoader__.load({
|
|
|
1633
1690
|
view: null,
|
|
1634
1691
|
viewRequest: null
|
|
1635
1692
|
}),
|
|
1636
|
-
persist:
|
|
1693
|
+
persist: CONVERSATION_STORE_KEY,
|
|
1637
1694
|
actions: {
|
|
1638
1695
|
setDraft: (d, text) => {
|
|
1639
1696
|
d.draft = text;
|
|
@@ -1654,6 +1711,23 @@ window.__ModuleLoader__.load({
|
|
|
1654
1711
|
}
|
|
1655
1712
|
});
|
|
1656
1713
|
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Read the persisted View preference before the Slot store is materialized.
|
|
1716
|
+
* @param sessionId - Session-scoped persistence suffix.
|
|
1717
|
+
* @returns the preferred View id, or null when storage has no usable value.
|
|
1718
|
+
*/
|
|
1719
|
+
function readConversationViewPreference(sessionId) {
|
|
1720
|
+
if (typeof localStorage === "undefined") return null;
|
|
1721
|
+
try {
|
|
1722
|
+
const raw = localStorage.getItem(`${CONVERSATION_STORE_KEY}.${sessionId}`);
|
|
1723
|
+
if (raw === null) return null;
|
|
1724
|
+
const stored = JSON.parse(raw);
|
|
1725
|
+
if (typeof stored !== "object" || stored === null || !("view" in stored)) return null;
|
|
1726
|
+
return typeof stored.view === "string" ? stored.view : null;
|
|
1727
|
+
} catch {
|
|
1728
|
+
return null;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1657
1731
|
//#endregion
|
|
1658
1732
|
//#region lib/types/client/service.js
|
|
1659
1733
|
/**
|
|
@@ -1801,6 +1875,7 @@ window.__ModuleLoader__.load({
|
|
|
1801
1875
|
finishRetirement = resolve;
|
|
1802
1876
|
});
|
|
1803
1877
|
const submission = session.beginSubmission({
|
|
1878
|
+
mode,
|
|
1804
1879
|
text,
|
|
1805
1880
|
images: attachments.map((attachment) => ({
|
|
1806
1881
|
previewUrl: attachment.previewUrl,
|
|
@@ -13177,7 +13252,6 @@ window.__ModuleLoader__.load({
|
|
|
13177
13252
|
"image.tooManyPixels": "图片分辨率过大,请压缩后重试",
|
|
13178
13253
|
"image.dimensionTooLarge": "图片宽高不能超过 {size}px,请缩小后重试",
|
|
13179
13254
|
"image.modelUnsupported": "当前模型不支持图片,请切换支持图片的模型",
|
|
13180
|
-
"image.subagentUnsupported": "子智能体会话暂不支持图片",
|
|
13181
13255
|
"image.sendFailed": "图片发送失败({reason}),请重新添加图片后再试",
|
|
13182
13256
|
"context.aria": "上下文已用 {percent}",
|
|
13183
13257
|
"context.used": "上下文已用",
|
|
@@ -13189,7 +13263,7 @@ window.__ModuleLoader__.load({
|
|
|
13189
13263
|
"settings.enter.queue": "排队发送",
|
|
13190
13264
|
"settings.enter.steer": "插话发送",
|
|
13191
13265
|
"access.preset.readOnly": "仅可查看",
|
|
13192
|
-
"access.preset.workspaceWrite": "
|
|
13266
|
+
"access.preset.workspaceWrite": "工作区内修改",
|
|
13193
13267
|
"access.preset.fullAccess": "完全权限",
|
|
13194
13268
|
"access.confirm.title": "确认启用完全权限?",
|
|
13195
13269
|
"access.confirm.description": "启用完全权限后,智能体将减少确认步骤,并且可以直接执行更多操作,包括敏感操作、文件修改或外部命令。仅建议在你信任当前任务时使用。",
|
|
@@ -13263,6 +13337,7 @@ window.__ModuleLoader__.load({
|
|
|
13263
13337
|
"web.contentTruncated": "内容已截断",
|
|
13264
13338
|
"details.running": "运行中…",
|
|
13265
13339
|
"queue.count": "{n} 条排队消息",
|
|
13340
|
+
"queue.image": "排队消息图片",
|
|
13266
13341
|
"queue.edit": "编辑排队消息",
|
|
13267
13342
|
"queue.edit.unsupported": "包含非文本内容,暂不支持编辑",
|
|
13268
13343
|
"queue.save": "保存排队消息",
|
|
@@ -13323,7 +13398,6 @@ window.__ModuleLoader__.load({
|
|
|
13323
13398
|
"image.tooManyPixels": "Image resolution is too high; compress it and try again",
|
|
13324
13399
|
"image.dimensionTooLarge": "Image sides must be at most {size}px; downscale it and try again",
|
|
13325
13400
|
"image.modelUnsupported": "The current model does not support images; switch to a model that does",
|
|
13326
|
-
"image.subagentUnsupported": "Subagent sessions do not support images yet",
|
|
13327
13401
|
"image.sendFailed": "Sending images failed ({reason}); re-add them and try again",
|
|
13328
13402
|
"context.aria": "{percent} of context used",
|
|
13329
13403
|
"context.used": "of context used",
|
|
@@ -13409,6 +13483,7 @@ window.__ModuleLoader__.load({
|
|
|
13409
13483
|
"web.contentTruncated": "Content truncated",
|
|
13410
13484
|
"details.running": "Running…",
|
|
13411
13485
|
"queue.count": "{n} queued messages",
|
|
13486
|
+
"queue.image": "Queued message image",
|
|
13412
13487
|
"queue.edit": "Edit queued message",
|
|
13413
13488
|
"queue.edit.unsupported": "Contains non-text content; editing is not supported yet",
|
|
13414
13489
|
"queue.save": "Save queued message",
|
|
@@ -13433,7 +13508,7 @@ window.__ModuleLoader__.load({
|
|
|
13433
13508
|
};
|
|
13434
13509
|
//#endregion
|
|
13435
13510
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/queue/QueueDock.module.css.mjs
|
|
13436
|
-
const css$7 = "._7yHdaG_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto calc(0px - var(--dsh-composer-stack-gap) - 3px);padding:0 var(--dsh-composer-dock-inset);flex:none}._7yHdaG_panel{background:var(--dsw-specific-tip);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px 12px 0 0;width:100%;padding:2px 0;position:relative;overflow:hidden}._7yHdaG_panel:after{border:1px solid var(--dsw-alias-border-l1);border-radius:inherit;content:\"\";pointer-events:none;border-bottom:none;position:absolute;inset:0}._7yHdaG_header{box-sizing:border-box;width:100%;height:36px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:8px;align-items:center;gap:10px;padding:4px 12px;display:flex}._7yHdaG_header:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_header:disabled{cursor:default}._7yHdaG_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_count{min-width:0;font-family:Inter, var(--dsw-font-family);flex:auto;font-size:13px;font-weight:500;line-height:24px}._7yHdaG_chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_list{max-height:180px;margin:0;padding:0;list-style:none;overflow-y:auto}._7yHdaG_row{box-sizing:border-box;border-radius:8px;align-items:center;gap:10px;width:100%;height:36px;padding:4px 5px 4px 12px;display:flex}._7yHdaG_row+._7yHdaG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}._7yHdaG_preview,._7yHdaG_editor{min-width:0;font:var(--dsw-font-xs-13);font-family:Inter, var(--dsw-font-family);flex:auto}._7yHdaG_preview{color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;word-break:break-word;overflow:hidden}._7yHdaG_editor{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);height:28px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:0 8px}._7yHdaG_editor:focus{border-color:var(--dsw-alias-state-business-primary)}._7yHdaG_actions{flex:none;align-items:center;gap:10px;display:flex}._7yHdaG_action{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;padding:0;display:grid}._7yHdaG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7yHdaG_action:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_action:disabled{cursor:default;opacity:.45}";
|
|
13511
|
+
const css$7 = "._7yHdaG_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto calc(0px - var(--dsh-composer-stack-gap) - 3px);padding:0 var(--dsh-composer-dock-inset);flex:none}._7yHdaG_panel{background:var(--dsw-specific-tip);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px 12px 0 0;width:100%;padding:2px 0;position:relative;overflow:hidden}._7yHdaG_panel:after{border:1px solid var(--dsw-alias-border-l1);border-radius:inherit;content:\"\";pointer-events:none;border-bottom:none;position:absolute;inset:0}._7yHdaG_header{box-sizing:border-box;width:100%;height:36px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:8px;align-items:center;gap:10px;padding:4px 12px;display:flex}._7yHdaG_header:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_header:disabled{cursor:default}._7yHdaG_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_count{min-width:0;font-family:Inter, var(--dsw-font-family);flex:auto;font-size:13px;font-weight:500;line-height:24px}._7yHdaG_chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_list{max-height:180px;margin:0;padding:0;list-style:none;overflow-y:auto}._7yHdaG_row{box-sizing:border-box;border-radius:8px;align-items:center;gap:10px;width:100%;height:36px;padding:4px 5px 4px 12px;display:flex}._7yHdaG_row+._7yHdaG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}._7yHdaG_thumbs{flex:none;gap:4px;display:flex}._7yHdaG_thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);object-fit:cover;border-radius:4px;width:24px;height:24px}._7yHdaG_preview,._7yHdaG_editor{min-width:0;font:var(--dsw-font-xs-13);font-family:Inter, var(--dsw-font-family);flex:auto}._7yHdaG_preview{color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;word-break:break-word;overflow:hidden}._7yHdaG_editor{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);height:28px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:0 8px}._7yHdaG_editor:focus{border-color:var(--dsw-alias-state-business-primary)}._7yHdaG_actions{flex:none;align-items:center;gap:10px;display:flex}._7yHdaG_action{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;padding:0;display:grid}._7yHdaG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7yHdaG_action:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_action:disabled{cursor:default;opacity:.45}";
|
|
13437
13512
|
const tagId$7 = "@deepseek-ai/dsh-client-ui-conversation/QueueDock.module.css";
|
|
13438
13513
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$7) + "]") === null) {
|
|
13439
13514
|
const tag = document.createElement("style");
|
|
@@ -13454,17 +13529,60 @@ window.__ModuleLoader__.load({
|
|
|
13454
13529
|
"list": "_7yHdaG_list",
|
|
13455
13530
|
"panel": "_7yHdaG_panel",
|
|
13456
13531
|
"preview": "_7yHdaG_preview",
|
|
13457
|
-
"row": "_7yHdaG_row"
|
|
13532
|
+
"row": "_7yHdaG_row",
|
|
13533
|
+
"thumb": "_7yHdaG_thumb",
|
|
13534
|
+
"thumbs": "_7yHdaG_thumbs"
|
|
13458
13535
|
};
|
|
13459
13536
|
//#endregion
|
|
13460
13537
|
//#region lib/types/client/queue/QueueDock.js
|
|
13461
13538
|
/**
|
|
13539
|
+
* Durable references carried by one queued row. Queue frames are wire data
|
|
13540
|
+
* despite their typed face, so an image block without a reference is skipped
|
|
13541
|
+
* rather than trusted.
|
|
13542
|
+
* @param content - the row's wire content blocks.
|
|
13543
|
+
* @returns the row's durable image references in block order.
|
|
13544
|
+
*/
|
|
13545
|
+
function queueImageRefs(content) {
|
|
13546
|
+
return content.flatMap((block) => {
|
|
13547
|
+
if (block.type !== "image") return [];
|
|
13548
|
+
const { attachment } = block;
|
|
13549
|
+
return attachment === void 0 ? [] : [attachment];
|
|
13550
|
+
});
|
|
13551
|
+
}
|
|
13552
|
+
/** One durable queued image as a fixed-size thumbnail; a load failure keeps the empty placeholder. */
|
|
13553
|
+
function QueueThumb({ attachment, loadImage, label }) {
|
|
13554
|
+
const [url, setUrl] = (0, react.useState)(null);
|
|
13555
|
+
(0, react.useEffect)(() => {
|
|
13556
|
+
let alive = true;
|
|
13557
|
+
loadImage(attachment).then((resolved) => {
|
|
13558
|
+
if (alive) setUrl(resolved);
|
|
13559
|
+
}, () => {});
|
|
13560
|
+
return () => {
|
|
13561
|
+
alive = false;
|
|
13562
|
+
};
|
|
13563
|
+
}, [attachment, loadImage]);
|
|
13564
|
+
return url === null ? (0, react_jsx_runtime.jsx)("span", {
|
|
13565
|
+
className: QueueDock_module_css_default.thumb,
|
|
13566
|
+
"aria-hidden": true
|
|
13567
|
+
}) : (0, react_jsx_runtime.jsx)("img", {
|
|
13568
|
+
className: QueueDock_module_css_default.thumb,
|
|
13569
|
+
src: url,
|
|
13570
|
+
alt: label
|
|
13571
|
+
});
|
|
13572
|
+
}
|
|
13573
|
+
/**
|
|
13462
13574
|
* Queue strip: one item renders directly; multiple items default to a
|
|
13463
13575
|
* collapsible count header; an empty queue renders nothing.
|
|
13464
13576
|
*/
|
|
13465
|
-
function QueueDock({ useSession, updateQueue, notify, t }) {
|
|
13577
|
+
function QueueDock({ useSession, updateQueue, notify, loadImage, t }) {
|
|
13466
13578
|
const inbox = useSession((s) => s.queue);
|
|
13467
13579
|
const queue = (0, react.useMemo)(() => inbox.filter((row) => row.placement === "queued"), [inbox]);
|
|
13580
|
+
const pendingSubmissions = useSession((s) => s.pendingSubmissions);
|
|
13581
|
+
const pendingQueue = (0, react.useMemo)(() => {
|
|
13582
|
+
const admitted = new Set(queue.flatMap((row) => row.rpcId === void 0 ? [] : [row.rpcId]));
|
|
13583
|
+
return pendingSubmissions.filter((submission) => submission.placement === "queued" && !admitted.has(submission.requestId));
|
|
13584
|
+
}, [pendingSubmissions, queue]);
|
|
13585
|
+
const rowCount = queue.length + pendingQueue.length;
|
|
13468
13586
|
const running = useSession((s) => s.running);
|
|
13469
13587
|
const queueMutable = useSession((s) => s.subagent === null);
|
|
13470
13588
|
const [editing, setEditing] = (0, react.useState)(null);
|
|
@@ -13472,18 +13590,19 @@ window.__ModuleLoader__.load({
|
|
|
13472
13590
|
const [collapsed, setCollapsed] = (0, react.useState)(true);
|
|
13473
13591
|
const listId = (0, react.useId)();
|
|
13474
13592
|
(0, react.useEffect)(() => {
|
|
13475
|
-
if (
|
|
13593
|
+
if (rowCount === 0 && !collapsed) setCollapsed(true);
|
|
13476
13594
|
if (editing !== null && (!queueMutable || !queue.some((row) => row.id === editing.id))) setEditing(null);
|
|
13477
13595
|
}, [
|
|
13478
13596
|
collapsed,
|
|
13479
13597
|
editing,
|
|
13480
13598
|
queue,
|
|
13481
|
-
queueMutable
|
|
13599
|
+
queueMutable,
|
|
13600
|
+
rowCount
|
|
13482
13601
|
]);
|
|
13483
|
-
if (
|
|
13602
|
+
if (rowCount === 0) return null;
|
|
13484
13603
|
const interactionActive = queueMutable && (editing !== null || busy !== null);
|
|
13485
13604
|
const expanded = !collapsed || interactionActive;
|
|
13486
|
-
const listVisible =
|
|
13605
|
+
const listVisible = rowCount === 1 || expanded;
|
|
13487
13606
|
const applyAction = async (itemId, action, failure) => {
|
|
13488
13607
|
setBusy(itemId);
|
|
13489
13608
|
try {
|
|
@@ -13511,7 +13630,7 @@ window.__ModuleLoader__.load({
|
|
|
13511
13630
|
"data-queue-dock": "",
|
|
13512
13631
|
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
13513
13632
|
className: QueueDock_module_css_default.panel,
|
|
13514
|
-
children: [
|
|
13633
|
+
children: [rowCount > 1 && (0, react_jsx_runtime.jsxs)("button", {
|
|
13515
13634
|
type: "button",
|
|
13516
13635
|
className: QueueDock_module_css_default.header,
|
|
13517
13636
|
"aria-controls": listId,
|
|
@@ -13528,7 +13647,7 @@ window.__ModuleLoader__.load({
|
|
|
13528
13647
|
}),
|
|
13529
13648
|
(0, react_jsx_runtime.jsx)("span", {
|
|
13530
13649
|
className: QueueDock_module_css_default.count,
|
|
13531
|
-
children: t("queue.count", { n:
|
|
13650
|
+
children: t("queue.count", { n: rowCount })
|
|
13532
13651
|
}),
|
|
13533
13652
|
(0, react_jsx_runtime.jsx)("span", {
|
|
13534
13653
|
className: QueueDock_module_css_default.chevron,
|
|
@@ -13536,130 +13655,162 @@ window.__ModuleLoader__.load({
|
|
|
13536
13655
|
children: expanded ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, {})
|
|
13537
13656
|
})
|
|
13538
13657
|
]
|
|
13539
|
-
}), (0, react_jsx_runtime.
|
|
13658
|
+
}), (0, react_jsx_runtime.jsxs)("ul", {
|
|
13540
13659
|
id: listId,
|
|
13541
13660
|
className: QueueDock_module_css_default.list,
|
|
13542
13661
|
hidden: !listVisible,
|
|
13543
|
-
children: listVisible && queue.map((row) =>
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
"
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
}
|
|
13567
|
-
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
13568
|
-
event.preventDefault();
|
|
13569
|
-
saveEdit();
|
|
13570
|
-
}
|
|
13571
|
-
}
|
|
13572
|
-
}) : (0, react_jsx_runtime.jsx)("span", {
|
|
13573
|
-
className: QueueDock_module_css_default.preview,
|
|
13574
|
-
children: (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(row.preview, [])
|
|
13575
|
-
}),
|
|
13576
|
-
queueMutable && (0, react_jsx_runtime.jsx)("div", {
|
|
13577
|
-
className: QueueDock_module_css_default.actions,
|
|
13578
|
-
children: editing?.id === row.id ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13579
|
-
label: t("queue.save"),
|
|
13580
|
-
side: "bottom",
|
|
13581
|
-
delayMs: 500,
|
|
13582
|
-
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13583
|
-
type: "button",
|
|
13584
|
-
className: QueueDock_module_css_default.action,
|
|
13585
|
-
"aria-label": t("queue.save"),
|
|
13586
|
-
disabled: busy !== null || editing.text.trim() === "",
|
|
13587
|
-
onClick: () => {
|
|
13588
|
-
saveEdit();
|
|
13589
|
-
},
|
|
13590
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, { size: 14 })
|
|
13591
|
-
})
|
|
13592
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13593
|
-
label: t("queue.cancelEdit"),
|
|
13594
|
-
side: "bottom",
|
|
13595
|
-
delayMs: 500,
|
|
13596
|
-
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13597
|
-
type: "button",
|
|
13598
|
-
className: QueueDock_module_css_default.action,
|
|
13599
|
-
"aria-label": t("queue.cancelEdit"),
|
|
13600
|
-
disabled: busy !== null,
|
|
13601
|
-
onClick: () => {
|
|
13662
|
+
children: [listVisible && queue.map((row) => {
|
|
13663
|
+
const imageRefs = queueImageRefs(row.content);
|
|
13664
|
+
return (0, react_jsx_runtime.jsxs)("li", {
|
|
13665
|
+
className: QueueDock_module_css_default.row,
|
|
13666
|
+
children: [
|
|
13667
|
+
rowCount === 1 && (0, react_jsx_runtime.jsx)("span", {
|
|
13668
|
+
className: QueueDock_module_css_default.lead,
|
|
13669
|
+
"aria-hidden": true,
|
|
13670
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutline14, {})
|
|
13671
|
+
}),
|
|
13672
|
+
editing?.id === row.id ? (0, react_jsx_runtime.jsx)("input", {
|
|
13673
|
+
autoFocus: true,
|
|
13674
|
+
className: QueueDock_module_css_default.editor,
|
|
13675
|
+
"aria-label": t("queue.edit"),
|
|
13676
|
+
value: editing.text,
|
|
13677
|
+
onChange: (event) => {
|
|
13678
|
+
setEditing({
|
|
13679
|
+
id: row.id,
|
|
13680
|
+
text: event.currentTarget.value
|
|
13681
|
+
});
|
|
13682
|
+
},
|
|
13683
|
+
onKeyDown: (event) => {
|
|
13684
|
+
if (event.key === "Escape") {
|
|
13602
13685
|
setEditing(null);
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13686
|
+
return;
|
|
13687
|
+
}
|
|
13688
|
+
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
13689
|
+
event.preventDefault();
|
|
13690
|
+
saveEdit();
|
|
13691
|
+
}
|
|
13692
|
+
}
|
|
13693
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [imageRefs.length > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
13694
|
+
className: QueueDock_module_css_default.thumbs,
|
|
13695
|
+
children: imageRefs.map((attachment, index) => (0, react_jsx_runtime.jsx)(QueueThumb, {
|
|
13696
|
+
attachment,
|
|
13697
|
+
loadImage,
|
|
13698
|
+
label: t("queue.image")
|
|
13699
|
+
}, `${attachment.attachmentId}:${index}`))
|
|
13700
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
13701
|
+
className: QueueDock_module_css_default.preview,
|
|
13702
|
+
children: (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(row.preview, [])
|
|
13703
|
+
})] }),
|
|
13704
|
+
queueMutable && (0, react_jsx_runtime.jsx)("div", {
|
|
13705
|
+
className: QueueDock_module_css_default.actions,
|
|
13706
|
+
children: editing?.id === row.id ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13707
|
+
label: t("queue.save"),
|
|
13609
13708
|
side: "bottom",
|
|
13610
13709
|
delayMs: 500,
|
|
13611
|
-
disabled: row.text === null,
|
|
13612
13710
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13613
13711
|
type: "button",
|
|
13614
13712
|
className: QueueDock_module_css_default.action,
|
|
13615
|
-
"aria-label": t("queue.
|
|
13616
|
-
|
|
13617
|
-
disabled: busy !== null || row.text === null,
|
|
13713
|
+
"aria-label": t("queue.save"),
|
|
13714
|
+
disabled: busy !== null || editing.text.trim() === "",
|
|
13618
13715
|
onClick: () => {
|
|
13619
|
-
|
|
13620
|
-
id: row.id,
|
|
13621
|
-
text: row.text
|
|
13622
|
-
});
|
|
13716
|
+
saveEdit();
|
|
13623
13717
|
},
|
|
13624
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
13718
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, { size: 14 })
|
|
13625
13719
|
})
|
|
13626
|
-
}),
|
|
13627
|
-
|
|
13628
|
-
label: t("queue.remove"),
|
|
13720
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13721
|
+
label: t("queue.cancelEdit"),
|
|
13629
13722
|
side: "bottom",
|
|
13630
13723
|
delayMs: 500,
|
|
13631
13724
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13632
13725
|
type: "button",
|
|
13633
13726
|
className: QueueDock_module_css_default.action,
|
|
13634
|
-
"aria-label": t("queue.
|
|
13727
|
+
"aria-label": t("queue.cancelEdit"),
|
|
13635
13728
|
disabled: busy !== null,
|
|
13636
13729
|
onClick: () => {
|
|
13637
|
-
|
|
13730
|
+
setEditing(null);
|
|
13638
13731
|
},
|
|
13639
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
13732
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
|
|
13640
13733
|
})
|
|
13641
|
-
}),
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13734
|
+
})] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
13735
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13736
|
+
label: t("queue.edit"),
|
|
13737
|
+
side: "bottom",
|
|
13738
|
+
delayMs: 500,
|
|
13739
|
+
disabled: row.text === null,
|
|
13740
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13741
|
+
type: "button",
|
|
13742
|
+
className: QueueDock_module_css_default.action,
|
|
13743
|
+
"aria-label": t("queue.edit"),
|
|
13744
|
+
title: row.text === null ? t("queue.edit.unsupported") : void 0,
|
|
13745
|
+
disabled: busy !== null || row.text === null,
|
|
13746
|
+
onClick: () => {
|
|
13747
|
+
if (row.text !== null) setEditing({
|
|
13748
|
+
id: row.id,
|
|
13749
|
+
text: row.text
|
|
13750
|
+
});
|
|
13751
|
+
},
|
|
13752
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 })
|
|
13753
|
+
})
|
|
13754
|
+
}),
|
|
13755
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13756
|
+
label: t("queue.remove"),
|
|
13757
|
+
side: "bottom",
|
|
13758
|
+
delayMs: 500,
|
|
13759
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13760
|
+
type: "button",
|
|
13761
|
+
className: QueueDock_module_css_default.action,
|
|
13762
|
+
"aria-label": t("queue.remove"),
|
|
13763
|
+
disabled: busy !== null,
|
|
13764
|
+
onClick: () => {
|
|
13765
|
+
applyAction(row.id, { kind: "remove" }, t("queue.removeFailed"));
|
|
13766
|
+
},
|
|
13767
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
|
|
13768
|
+
})
|
|
13769
|
+
}),
|
|
13770
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
13771
|
+
label: t("queue.steer"),
|
|
13772
|
+
side: "bottom",
|
|
13773
|
+
delayMs: 500,
|
|
13774
|
+
disabled: !running,
|
|
13775
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
13776
|
+
type: "button",
|
|
13777
|
+
className: QueueDock_module_css_default.action,
|
|
13778
|
+
"aria-label": t("queue.steer"),
|
|
13779
|
+
title: running ? void 0 : t("queue.steer.unavailable"),
|
|
13780
|
+
disabled: busy !== null || !running,
|
|
13781
|
+
onClick: () => {
|
|
13782
|
+
applyAction(row.id, { kind: "steer" }, t("queue.steerFailed"));
|
|
13783
|
+
},
|
|
13784
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline14, {})
|
|
13785
|
+
})
|
|
13657
13786
|
})
|
|
13658
|
-
})
|
|
13659
|
-
|
|
13787
|
+
] })
|
|
13788
|
+
})
|
|
13789
|
+
]
|
|
13790
|
+
}, row.id);
|
|
13791
|
+
}), listVisible && pendingQueue.map((submission) => (0, react_jsx_runtime.jsxs)("li", {
|
|
13792
|
+
className: QueueDock_module_css_default.row,
|
|
13793
|
+
"data-submission-echo": "",
|
|
13794
|
+
children: [
|
|
13795
|
+
rowCount === 1 && (0, react_jsx_runtime.jsx)("span", {
|
|
13796
|
+
className: QueueDock_module_css_default.lead,
|
|
13797
|
+
"aria-hidden": true,
|
|
13798
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutline14, {})
|
|
13799
|
+
}),
|
|
13800
|
+
submission.images.length > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
13801
|
+
className: QueueDock_module_css_default.thumbs,
|
|
13802
|
+
children: submission.images.map((image, index) => (0, react_jsx_runtime.jsx)("img", {
|
|
13803
|
+
className: QueueDock_module_css_default.thumb,
|
|
13804
|
+
src: image.previewUrl,
|
|
13805
|
+
alt: t("queue.image")
|
|
13806
|
+
}, `${image.previewUrl}:${index}`))
|
|
13807
|
+
}),
|
|
13808
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
13809
|
+
className: QueueDock_module_css_default.preview,
|
|
13810
|
+
children: (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(submission.text, [])
|
|
13660
13811
|
})
|
|
13661
13812
|
]
|
|
13662
|
-
},
|
|
13813
|
+
}, submission.requestId))]
|
|
13663
13814
|
})]
|
|
13664
13815
|
})
|
|
13665
13816
|
});
|
|
@@ -13670,7 +13821,8 @@ window.__ModuleLoader__.load({
|
|
|
13670
13821
|
inject: [
|
|
13671
13822
|
"slots",
|
|
13672
13823
|
"conversation",
|
|
13673
|
-
"sessions"
|
|
13824
|
+
"sessions",
|
|
13825
|
+
"uiConversation"
|
|
13674
13826
|
],
|
|
13675
13827
|
apply(ctx) {
|
|
13676
13828
|
ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
@@ -13687,7 +13839,8 @@ window.__ModuleLoader__.load({
|
|
|
13687
13839
|
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
13688
13840
|
notify: (level, text) => {
|
|
13689
13841
|
conversation.input.for(actx).notify(level, text);
|
|
13690
|
-
}
|
|
13842
|
+
},
|
|
13843
|
+
loadImage: (attachment) => ctx.uiConversation.imageUrl(sessionId, attachment)
|
|
13691
13844
|
};
|
|
13692
13845
|
}
|
|
13693
13846
|
}, QueueDock));
|
|
@@ -14278,13 +14431,20 @@ window.__ModuleLoader__.load({
|
|
|
14278
14431
|
});
|
|
14279
14432
|
}
|
|
14280
14433
|
//#endregion
|
|
14281
|
-
//#region lib/types/client/
|
|
14282
|
-
/** Strict per-session header/body content inserted into the resident conversation layout. */
|
|
14434
|
+
//#region lib/types/client/view-selection.js
|
|
14283
14435
|
const DEFAULT_VIEW_ID = "chat";
|
|
14284
|
-
/**
|
|
14436
|
+
/**
|
|
14437
|
+
* Resolve a preferred registered View, then Chat, without choosing another View.
|
|
14438
|
+
* @param tabs - currently registered Views.
|
|
14439
|
+
* @param selectedId - preferred View identity, when one is stored.
|
|
14440
|
+
* @returns the selected View, Chat fallback, or undefined when neither is registered.
|
|
14441
|
+
*/
|
|
14285
14442
|
function resolveActiveView(tabs, selectedId) {
|
|
14286
14443
|
return (selectedId === null ? void 0 : tabs.find((view) => view.id === selectedId)) ?? tabs.find((view) => view.id === DEFAULT_VIEW_ID);
|
|
14287
14444
|
}
|
|
14445
|
+
//#endregion
|
|
14446
|
+
//#region lib/types/client/skeleton/ConversationSession.js
|
|
14447
|
+
/** Strict per-session header/body content inserted into the resident conversation layout. */
|
|
14288
14448
|
function deriveAncestry(list, id) {
|
|
14289
14449
|
const chain = [];
|
|
14290
14450
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -14315,7 +14475,7 @@ window.__ModuleLoader__.load({
|
|
|
14315
14475
|
* @param props - Strict Session store, view ledger, navigation, render, and locale shares.
|
|
14316
14476
|
* @returns the hidden blank-session header or visible title and tabs.
|
|
14317
14477
|
*/
|
|
14318
|
-
function ConversationSessionHeader({ sessionId, useSession, useSessions, useConversation, useConversationViews, useStore,
|
|
14478
|
+
function ConversationSessionHeader({ sessionId, useSession, useSessions, useConversation, useConversationViews, useStore, renderSlot, open, selectView, t }) {
|
|
14319
14479
|
const tabs = useConversationViews((value) => value);
|
|
14320
14480
|
const active = resolveActiveView(tabs, useStore((s) => s.view));
|
|
14321
14481
|
const ancestry = useSessions((s) => deriveAncestry(s, sessionId), equalBreadcrumbs);
|
|
@@ -14379,7 +14539,7 @@ window.__ModuleLoader__.load({
|
|
|
14379
14539
|
"aria-selected": viewTab.id === active?.id,
|
|
14380
14540
|
className: clsx(ConversationRoot_module_css_default.tab, viewTab.id === active?.id && ConversationRoot_module_css_default.tabActive),
|
|
14381
14541
|
onClick: () => {
|
|
14382
|
-
|
|
14542
|
+
selectView(viewTab.id);
|
|
14383
14543
|
},
|
|
14384
14544
|
children: viewTab.label
|
|
14385
14545
|
}, viewTab.id))
|
|
@@ -14392,7 +14552,7 @@ window.__ModuleLoader__.load({
|
|
|
14392
14552
|
* @param props - Strict Session input/store, view ledger, and render shares.
|
|
14393
14553
|
* @returns the active view area, or null while the Session remains blank.
|
|
14394
14554
|
*/
|
|
14395
|
-
function ConversationSession({ useSession, useConversation, useConversationViews, useInput, inputActions, useStore, actions, renderSlot, bindDraftMirror }) {
|
|
14555
|
+
function ConversationSession({ useSession, useConversation, useConversationViews, useInput, inputActions, useStore, actions, renderSlot, bindDraftMirror, openView }) {
|
|
14396
14556
|
const active = resolveActiveView(useConversationViews((value) => value), useStore((s) => s.view));
|
|
14397
14557
|
const session = useSession((s) => s);
|
|
14398
14558
|
const conversation = useConversation((s) => s);
|
|
@@ -14411,7 +14571,7 @@ window.__ModuleLoader__.load({
|
|
|
14411
14571
|
className: ConversationRoot_module_css_default.viewArea,
|
|
14412
14572
|
children: active !== void 0 && renderSlot("conversation.view", {
|
|
14413
14573
|
viewRequest,
|
|
14414
|
-
openView
|
|
14574
|
+
openView,
|
|
14415
14575
|
completeViewRequest: actions.completeViewRequest
|
|
14416
14576
|
}, { only: active.id })
|
|
14417
14577
|
});
|
|
@@ -14507,7 +14667,7 @@ window.__ModuleLoader__.load({
|
|
|
14507
14667
|
const recentlyComposing = () => composing || Date.now() < composingUntil;
|
|
14508
14668
|
const arrow = (key) => (event) => {
|
|
14509
14669
|
const inComposition = event !== null && isComposingEvent(event, recentlyComposing);
|
|
14510
|
-
if (handlers.arbitrate(key, inComposition)
|
|
14670
|
+
if (handlers.arbitrate(key, inComposition) !== "pass") {
|
|
14511
14671
|
event?.preventDefault();
|
|
14512
14672
|
return true;
|
|
14513
14673
|
}
|
|
@@ -14574,7 +14734,7 @@ window.__ModuleLoader__.load({
|
|
|
14574
14734
|
}
|
|
14575
14735
|
/**
|
|
14576
14736
|
* Product copy for a host attachment rejection (the `details.reason` of
|
|
14577
|
-
* `session/attachment-invalid` or `subagent/attachment-
|
|
14737
|
+
* `session/attachment-invalid` or `subagent/attachment-invalid`).
|
|
14578
14738
|
* User-solvable reasons name the limit and the way out;
|
|
14579
14739
|
* reasons the user cannot act on fold into one send-failed line carrying the
|
|
14580
14740
|
* reason code for a bug report.
|
|
@@ -14586,7 +14746,6 @@ window.__ModuleLoader__.load({
|
|
|
14586
14746
|
function attachmentErrorText(t, reason, limits) {
|
|
14587
14747
|
switch (reason) {
|
|
14588
14748
|
case "MODEL_DOES_NOT_SUPPORT_IMAGES": return t("image.modelUnsupported");
|
|
14589
|
-
case "SUBAGENT_IMAGE_UNSUPPORTED": return t("image.subagentUnsupported");
|
|
14590
14749
|
case "IMAGE_TOO_MANY_PIXELS": return t("image.tooManyPixels");
|
|
14591
14750
|
case "IMAGE_DIMENSION_TOO_LARGE":
|
|
14592
14751
|
if (limits !== void 0) return t("image.dimensionTooLarge", { size: limits.maxImageDimension });
|
|
@@ -15122,7 +15281,7 @@ window.__ModuleLoader__.load({
|
|
|
15122
15281
|
(0, react.useEffect)(() => {
|
|
15123
15282
|
if (promptError === null) return;
|
|
15124
15283
|
const { error } = promptError;
|
|
15125
|
-
showToast(error.code === "session/attachment-invalid" || error.code === "subagent/attachment-
|
|
15284
|
+
showToast(error.code === "session/attachment-invalid" || error.code === "subagent/attachment-invalid" ? attachmentErrorText(t, error.details.reason, imageLimits) : `${error.message} (${error.code})`);
|
|
15126
15285
|
}, [
|
|
15127
15286
|
promptError,
|
|
15128
15287
|
showToast,
|
|
@@ -15774,24 +15933,43 @@ window.__ModuleLoader__.load({
|
|
|
15774
15933
|
}
|
|
15775
15934
|
return tabs;
|
|
15776
15935
|
};
|
|
15936
|
+
const activateView = (sessionId, preferred) => {
|
|
15937
|
+
const active = resolveActiveView(viewTabs(), preferred);
|
|
15938
|
+
if (active !== void 0) uiConversation.binding(sessionId).activate(active.id);
|
|
15939
|
+
};
|
|
15940
|
+
const restoreView = (sessionId) => {
|
|
15941
|
+
activateView(sessionId, readConversationViewPreference(sessionId));
|
|
15942
|
+
};
|
|
15943
|
+
const restoreCurrentView = () => {
|
|
15944
|
+
const sessionId = sessions.list.getSnapshot().current;
|
|
15945
|
+
if (sessionId !== void 0 && sessions.binding(sessionId) !== void 0) restoreView(sessionId);
|
|
15946
|
+
};
|
|
15777
15947
|
const conversationViews = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(viewTabs());
|
|
15778
15948
|
const refreshViews = () => {
|
|
15779
15949
|
const current = conversationViews.getSnapshot();
|
|
15780
15950
|
const next = viewTabs();
|
|
15781
|
-
if (current.length === next.length && current.every((tab, index) => {
|
|
15951
|
+
if (!(current.length === next.length && current.every((tab, index) => {
|
|
15782
15952
|
const candidate = next.at(index);
|
|
15783
15953
|
return candidate !== void 0 && tab.id === candidate.id && tab.label === candidate.label;
|
|
15784
|
-
}))
|
|
15785
|
-
|
|
15954
|
+
}))) conversationViews.set(next);
|
|
15955
|
+
restoreCurrentView();
|
|
15786
15956
|
};
|
|
15787
15957
|
ctx.effect(() => {
|
|
15958
|
+
let currentSessionId = sessions.list.getSnapshot().current;
|
|
15788
15959
|
const disposeViews = slots.subscribe("conversation.view", refreshViews);
|
|
15789
15960
|
const disposeLocale = ctx.locale.subscribe(refreshViews);
|
|
15961
|
+
const disposeCurrent = sessions.list.subscribe(() => {
|
|
15962
|
+
const nextSessionId = sessions.list.getSnapshot().current;
|
|
15963
|
+
if (nextSessionId === currentSessionId) return;
|
|
15964
|
+
currentSessionId = nextSessionId;
|
|
15965
|
+
restoreCurrentView();
|
|
15966
|
+
});
|
|
15790
15967
|
return () => {
|
|
15968
|
+
disposeCurrent();
|
|
15791
15969
|
disposeLocale();
|
|
15792
15970
|
disposeViews();
|
|
15793
15971
|
};
|
|
15794
|
-
}, "ui-conversation: View
|
|
15972
|
+
}, "ui-conversation: View selection");
|
|
15795
15973
|
const inputHub = new InputHub(ctx, t);
|
|
15796
15974
|
const composerBlocks = new ComposerBlockRegistry();
|
|
15797
15975
|
ctx.uiSession.provide({
|
|
@@ -15799,9 +15977,11 @@ window.__ModuleLoader__.load({
|
|
|
15799
15977
|
props: ["inputActions"],
|
|
15800
15978
|
resolve: (binding) => {
|
|
15801
15979
|
const shell = inputHub.shellFor(binding);
|
|
15980
|
+
const conversation = uiConversation.binding(binding);
|
|
15981
|
+
restoreView(binding.sessionId);
|
|
15802
15982
|
return {
|
|
15803
15983
|
hooks: {
|
|
15804
|
-
conversation:
|
|
15984
|
+
conversation: conversation.snapshot,
|
|
15805
15985
|
input: shell.state
|
|
15806
15986
|
},
|
|
15807
15987
|
props: { inputActions: shell.actions }
|
|
@@ -15889,9 +16069,13 @@ window.__ModuleLoader__.load({
|
|
|
15889
16069
|
scope: "session"
|
|
15890
16070
|
} },
|
|
15891
16071
|
store: conversationStore,
|
|
15892
|
-
inject: (sessionId,
|
|
16072
|
+
inject: (sessionId, actions) => ({
|
|
15893
16073
|
hooks: { conversationViews },
|
|
15894
|
-
bindDraftMirror: (write) => inputHub.shell(sessionId).bindMirror(write)
|
|
16074
|
+
bindDraftMirror: (write) => inputHub.shell(sessionId).bindMirror(write),
|
|
16075
|
+
openView: (view, focus) => {
|
|
16076
|
+
activateView(sessionId, view);
|
|
16077
|
+
actions.openView(view, focus);
|
|
16078
|
+
}
|
|
15895
16079
|
})
|
|
15896
16080
|
}, ConversationSession);
|
|
15897
16081
|
const registerConversationHeader = () => slots.register({
|
|
@@ -15912,10 +16096,14 @@ window.__ModuleLoader__.load({
|
|
|
15912
16096
|
}
|
|
15913
16097
|
},
|
|
15914
16098
|
store: conversationStore,
|
|
15915
|
-
inject: () => ({
|
|
16099
|
+
inject: (sessionId, actions) => ({
|
|
15916
16100
|
hooks: { conversationViews },
|
|
15917
16101
|
open: (id) => {
|
|
15918
16102
|
sessions.open(id);
|
|
16103
|
+
},
|
|
16104
|
+
selectView: (view) => {
|
|
16105
|
+
activateView(sessionId, view);
|
|
16106
|
+
actions.setView(view);
|
|
15919
16107
|
}
|
|
15920
16108
|
})
|
|
15921
16109
|
}, ConversationSessionHeader);
|