dsh-lcx-codex 0.4.2 → 0.4.3-pre.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -205
- package/cordis.patch.yml +3 -20
- package/lib/client.js +309 -146
- package/lib/compact-v2.js +218 -199
- package/lib/dsh-compat.js +232 -100
- package/lib/dsh-responses.js +452 -277
- package/lib/grok-native-search.js +254 -0
- package/lib/index.js +1013 -757
- package/lib/json-store.js +50 -31
- package/lib/native-checkpoint.js +520 -194
- package/lib/responses-request.js +109 -121
- package/lib/responses-stream.js +1249 -447
- package/lib/route.js +411 -369
- package/lib/service-mutex.js +73 -64
- package/lib/token-budget.js +176 -108
- package/lib/transport.js +280 -68
- package/lib/types/client/index.d.ts +6 -0
- package/lib/types/compact-v2.d.ts +104 -0
- package/lib/types/dsh-compat.d.ts +78 -0
- package/lib/types/dsh-responses.d.ts +82 -0
- package/lib/types/grok-native-search.d.ts +34 -0
- package/lib/types/index.d.ts +83 -0
- package/lib/types/json-store.d.ts +10 -0
- package/lib/types/native-checkpoint.d.ts +213 -0
- package/lib/types/responses-request.d.ts +59 -0
- package/lib/types/responses-stream.d.ts +64 -0
- package/lib/types/route.d.ts +153 -0
- package/lib/types/service-mutex.d.ts +14 -0
- package/lib/types/token-budget.d.ts +50 -0
- package/lib/types/transport.d.ts +21 -0
- package/lib/types/web-run-output.d.ts +29 -0
- package/lib/types/web-search-alpha.d.ts +286 -0
- package/lib/types/web-search-capability.d.ts +26 -0
- package/lib/types/web-search-hosted.d.ts +246 -0
- package/lib/types/web-search-ref-store.d.ts +22 -0
- package/lib/web-run-output.js +167 -18
- package/lib/web-search-alpha.js +865 -163
- package/lib/web-search-capability.js +55 -65
- package/lib/web-search-hosted.js +210 -32
- package/lib/web-search-ref-store.js +63 -59
- package/package.json +89 -29
- package/ARCHITECTURE.md +0 -117
- package/CHANGELOG.md +0 -224
- package/README_EN.md +0 -277
- package/assets/dsh-lcx-codex-banner.jpg +0 -0
- package/lib/legacy-v3.js +0 -20
- package/lib/responses-replay.js +0 -68
- package/scripts/probe-alpha.mjs +0 -43
- package/scripts/validate-dsh-schema.mjs +0 -31
package/lib/client.js
CHANGED
|
@@ -1,168 +1,331 @@
|
|
|
1
|
+
// src/client/index.tsx
|
|
1
2
|
window.__ModuleLoader__.load({
|
|
2
|
-
id:
|
|
3
|
-
factory: (
|
|
4
|
-
const module = { exports: {} }
|
|
5
|
-
const exports = module.exports
|
|
6
|
-
const React =
|
|
7
|
-
const { createSnapshotStore } =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
tag.dataset.pluginCss = 'dsh-lcx-codex'
|
|
29
|
-
tag.textContent = css
|
|
30
|
-
document.head.appendChild(tag)
|
|
3
|
+
id: "dsh-lcx-codex",
|
|
4
|
+
factory: (require2) => {
|
|
5
|
+
const module = { exports: {} };
|
|
6
|
+
const exports = module.exports;
|
|
7
|
+
const React = require2("react");
|
|
8
|
+
const { createSnapshotStore } = require2(
|
|
9
|
+
"@deepseek-ai/dsh-client-store"
|
|
10
|
+
);
|
|
11
|
+
const NAMESPACE = "lcx-codex";
|
|
12
|
+
const FIELDS = [
|
|
13
|
+
"enabled",
|
|
14
|
+
"webSearch",
|
|
15
|
+
"advancedHostedSearch",
|
|
16
|
+
"alphaSearch",
|
|
17
|
+
"grokNativeWebSearch",
|
|
18
|
+
"grokNativeXSearch"
|
|
19
|
+
];
|
|
20
|
+
const DEFAULTS = Object.fromEntries(
|
|
21
|
+
FIELDS.map((field) => [field, false])
|
|
22
|
+
);
|
|
23
|
+
const css = `.lcx-card{border:1px solid var(--dsw-alias-border-l2);border-radius:12px;list-style:none}.lcx-head{width:100%;display:flex;justify-content:space-between;padding:14px 16px;border:0;background:transparent;color:inherit}.lcx-body{border-top:1px solid var(--dsw-alias-border-l2);padding:12px 16px}.lcx-row{display:flex;gap:9px;padding:8px 0}.lcx-row small,.lcx-help{display:block;font-size:12px;line-height:17px;color:var(--dsw-alias-label-tertiary)}.lcx-group{border-top:1px solid var(--dsw-alias-border-l2);margin-top:10px;padding-top:14px}.lcx-group strong{font-size:14px}.lcx-foot{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.lcx-foot button{padding:6px 12px;border-radius:8px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:inherit}`;
|
|
24
|
+
if (typeof document !== "undefined" && !document.querySelector('style[data-plugin-css="dsh-lcx-codex"]')) {
|
|
25
|
+
const tag = document.createElement("style");
|
|
26
|
+
tag.dataset.pluginCss = "dsh-lcx-codex";
|
|
27
|
+
tag.textContent = css;
|
|
28
|
+
document.head.appendChild(tag);
|
|
31
29
|
}
|
|
32
30
|
const copy = {
|
|
33
31
|
zh: {
|
|
34
|
-
title:
|
|
35
|
-
desc:
|
|
36
|
-
enabled:
|
|
37
|
-
enabledHelp:
|
|
38
|
-
web:
|
|
39
|
-
webHelp:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
endpoint: 'Responses 地址',
|
|
55
|
-
model: 'GPT 模型',
|
|
56
|
-
save: '保存', discard: '放弃修改', saving: '保存中…',
|
|
32
|
+
title: "Responses / Codex \u80FD\u529B",
|
|
33
|
+
desc: "LCX \u8DDF\u968F DSH \u5F53\u524D\u4F1A\u8BDD\u9009\u62E9\u7684 GPT Responses route\uFF1B\u6A21\u578B\u3001endpoint \u548C credential \u7EE7\u7EED\u53EA\u7531 DSH \u7BA1\u7406\u3002",
|
|
34
|
+
enabled: "\u542F\u7528 LCX\uFF08\u63A5\u7BA1\u5F53\u524D GPT Responses \u4F1A\u8BDD\uFF09",
|
|
35
|
+
enabledHelp: "\u6B64\u5F00\u5173\u4EC5\u63A5\u7BA1 GPT Responses \u4F1A\u8BDD\uFF1BGrok \u539F\u751F\u641C\u7D22\u7531\u4E0B\u65B9\u72EC\u7ACB\u5F00\u5173\u63A7\u5236\uFF0C\u5176\u4ED6\u975E GPT \u6A21\u578B\u7EE7\u7EED\u4F7F\u7528 DSH \u539F\u751F\u8DEF\u5F84\u3002",
|
|
36
|
+
web: "\u4F7F\u7528 GPT Hosted Search \u4F5C\u4E3A DSH web_search \u540E\u7AEF",
|
|
37
|
+
webHelp: "\u4E0D\u4F1A\u65B0\u589E\u7B2C\u4E8C\u4E2A\u666E\u901A\u641C\u7D22\u5DE5\u5177\uFF1B\u666E\u901A web_search \u81EA\u52A8\u8DDF\u968F\u5F53\u524D Agent \u7684 GPT Responses route\u3002",
|
|
38
|
+
advanced: "\u542F\u7528\u9AD8\u7EA7 Hosted \u5DE5\u5177\uFF08websearch_gpt_advanced\uFF09",
|
|
39
|
+
advancedHelp: "\u53EA\u5728\u9700\u8981\u57DF\u540D\u8FC7\u6EE4\u3001\u4F4D\u7F6E\u3001search context\u3001\u56FE\u7247\u7B49\u539F\u751F Hosted \u53C2\u6570\u65F6\u4F7F\u7528\uFF1B\u9ED8\u8BA4\u5173\u95ED\u4EE5\u4FDD\u6301\u5DE5\u5177 schema \u7A33\u5B9A\u3002",
|
|
40
|
+
alpha: "\u542F\u7528 Alpha command\uFF08websearch_alpha\uFF09",
|
|
41
|
+
alphaHelp: "\u4EC5 capability probe \u5BF9\u5F53\u524D route/schema \u9A8C\u8BC1\u901A\u8FC7\u540E\u624D\u771F\u6B63\u6CE8\u518C\u3002",
|
|
42
|
+
grokTitle: "Grok \u539F\u751F\u641C\u7D22",
|
|
43
|
+
grokDesc: "\u4F7F\u7528 DSH \u5F53\u524D\u9009\u62E9\u7684 Grok \u6A21\u578B\u53CA\u5176\u670D\u52A1\u914D\u7F6E\uFF1B\u4E0E GPT \u529F\u80FD\u5F00\u5173\u72EC\u7ACB\u3002\u5F00\u542F\u4EFB\u4E00\u641C\u7D22\u540E\uFF0CGrok \u4EC5\u4F7F\u7528\u539F\u751F\u641C\u7D22\uFF0C\u7F51\u9875\u8BFB\u53D6\u548C\u5176\u4ED6\u5DE5\u5177\u4ECD\u53EF\u7528\u3002",
|
|
44
|
+
grokWeb: "\u542F\u7528\u539F\u751F Web Search",
|
|
45
|
+
grokWebHelp: "\u4F7F\u7528 Grok \u7684\u539F\u751F\u7F51\u9875\u641C\u7D22\u3002",
|
|
46
|
+
grokX: "\u542F\u7528\u539F\u751F X Search",
|
|
47
|
+
grokXHelp: "\u4F7F\u7528 Grok \u7684\u539F\u751F X \u641C\u7D22\uFF1B\u5355\u72EC\u5F00\u542F\u4E5F\u4E0D\u4F1A\u4F7F\u7528 DSH \u641C\u7D22\u3002",
|
|
48
|
+
save: "\u4FDD\u5B58",
|
|
49
|
+
discard: "\u653E\u5F03\u4FEE\u6539",
|
|
50
|
+
saving: "\u4FDD\u5B58\u4E2D\u2026",
|
|
51
|
+
saveError: "\u672A\u80FD\u786E\u8BA4\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002\u4FEE\u6539\u5DF2\u4FDD\u7559\uFF0C\u8BF7\u91CD\u8BD5\u6216\u653E\u5F03\u4FEE\u6539\u4EE5\u67E5\u770B\u5F53\u524D\u8BBE\u7F6E\u3002"
|
|
57
52
|
},
|
|
58
53
|
en: {
|
|
59
|
-
title:
|
|
60
|
-
desc:
|
|
61
|
-
enabled:
|
|
62
|
-
enabledHelp:
|
|
63
|
-
web:
|
|
64
|
-
webHelp:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
54
|
+
title: "Responses / Codex capabilities",
|
|
55
|
+
desc: "LCX follows the GPT Responses route selected by the current DSH session. Model, endpoint and credentials remain DSH-owned.",
|
|
56
|
+
enabled: "Enable LCX (own current GPT Responses conversation)",
|
|
57
|
+
enabledHelp: "Applies only to GPT Responses conversations. Grok native search is controlled independently below; other non-GPT models continue through DSH normally.",
|
|
58
|
+
web: "Use GPT Hosted Search as DSH web_search backend",
|
|
59
|
+
webHelp: "Keeps DSH web_search as the single ordinary search tool and follows the active Agent GPT Responses route.",
|
|
60
|
+
advanced: "Enable advanced Hosted tool (websearch_gpt_advanced)",
|
|
61
|
+
advancedHelp: "Only for native Hosted controls such as domains, location, context size and image search; off by default for stable tool schemas.",
|
|
62
|
+
alpha: "Enable Alpha command (websearch_alpha)",
|
|
63
|
+
alphaHelp: "Registered only after a matching capability probe.",
|
|
64
|
+
grokTitle: "Grok native search",
|
|
65
|
+
grokDesc: "Uses the Grok model and provider profile currently selected in DSH, independently of the GPT switch. When either search is enabled, Grok uses native search while page reading and other tools remain available.",
|
|
66
|
+
grokWeb: "Enable native Web Search",
|
|
67
|
+
grokWebHelp: "Use Grok's native web search.",
|
|
68
|
+
grokX: "Enable native X Search",
|
|
69
|
+
grokXHelp: "Use Grok's native X search. Enabling it alone also avoids DSH search.",
|
|
70
|
+
save: "Save",
|
|
71
|
+
discard: "Discard",
|
|
72
|
+
saving: "Saving\u2026",
|
|
73
|
+
saveError: "Could not confirm settings were saved. Changes are kept; retry or discard to view current settings."
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function valueFrom(snapshot) {
|
|
77
|
+
const value = snapshot.value ?? {};
|
|
78
|
+
return {
|
|
79
|
+
...DEFAULTS,
|
|
80
|
+
...Object.fromEntries(
|
|
81
|
+
FIELDS.map((field) => [field, Boolean(value[field])])
|
|
82
|
+
)
|
|
83
|
+
};
|
|
82
84
|
}
|
|
83
|
-
const lang = () => String(globalThis.navigator?.language ?? '').toLowerCase().startsWith('zh') ? 'zh' : 'en'
|
|
84
|
-
function valueFrom(snapshot) { return { ...DEFAULTS, ...(snapshot.value ?? {}) } }
|
|
85
85
|
class Controller {
|
|
86
|
+
scope;
|
|
87
|
+
draft;
|
|
88
|
+
dirty;
|
|
89
|
+
saving;
|
|
90
|
+
saveError;
|
|
91
|
+
store;
|
|
92
|
+
stop;
|
|
86
93
|
constructor(scope) {
|
|
87
|
-
this.scope = scope;
|
|
88
|
-
this.
|
|
89
|
-
this.
|
|
94
|
+
this.scope = scope;
|
|
95
|
+
this.draft = null;
|
|
96
|
+
this.dirty = false;
|
|
97
|
+
this.saving = false;
|
|
98
|
+
this.saveError = false;
|
|
99
|
+
this.store = createSnapshotStore(this.projection());
|
|
100
|
+
this.stop = scope.subscribe(() => {
|
|
101
|
+
if (!this.dirty) this.draft = null;
|
|
102
|
+
this.publish();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
snapshot() {
|
|
106
|
+
return this.scope.getSnapshot();
|
|
107
|
+
}
|
|
108
|
+
value() {
|
|
109
|
+
return valueFrom(this.snapshot());
|
|
110
|
+
}
|
|
111
|
+
draftValue() {
|
|
112
|
+
return { ...this.value(), ...this.draft ?? {} };
|
|
90
113
|
}
|
|
91
|
-
snapshot() { return this.scope.getSnapshot() }
|
|
92
|
-
value() { return valueFrom(this.snapshot()) }
|
|
93
|
-
draftValue() { return { ...this.value(), ...(this.draft ?? {}) } }
|
|
94
|
-
field(name) { return this.draftValue()[name] }
|
|
95
114
|
projection() {
|
|
96
|
-
const s = this.snapshot()
|
|
97
|
-
|
|
115
|
+
const s = this.snapshot(), value = this.draftValue(), fields = Object.fromEntries(
|
|
116
|
+
FIELDS.map((field) => [field, { value: Boolean(value[field]) }])
|
|
117
|
+
);
|
|
98
118
|
return {
|
|
99
|
-
available: s.status ===
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
119
|
+
available: s.status === "ready",
|
|
120
|
+
writable: s.writable,
|
|
121
|
+
dirty: this.dirty,
|
|
122
|
+
saving: this.saving,
|
|
123
|
+
saveError: this.saveError,
|
|
124
|
+
...fields
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
publish() {
|
|
128
|
+
this.store.set(this.projection());
|
|
129
|
+
}
|
|
130
|
+
edit(field, value) {
|
|
131
|
+
if (!FIELDS.includes(field) || this.saving || !this.snapshot().writable) return;
|
|
132
|
+
this.draft = {
|
|
133
|
+
...this.draft,
|
|
134
|
+
[field]: Boolean(value)
|
|
135
|
+
};
|
|
136
|
+
if (this.value()[field] === Boolean(value)) delete this.draft[field];
|
|
137
|
+
this.dirty = Object.keys(this.draft).length > 0;
|
|
138
|
+
this.saveError = false;
|
|
139
|
+
this.publish();
|
|
140
|
+
}
|
|
141
|
+
discard() {
|
|
142
|
+
if (this.saving) return;
|
|
143
|
+
this.draft = null;
|
|
144
|
+
this.dirty = false;
|
|
145
|
+
this.saveError = false;
|
|
146
|
+
this.publish();
|
|
106
147
|
}
|
|
107
|
-
publish() { this.store.set(this.projection()) }
|
|
108
|
-
edit(field, value) { this.draft = { ...(this.draft ?? this.value()), [field]: value }; this.dirty = true; this.publish() }
|
|
109
|
-
discard() { this.draft = null; this.dirty = false; this.publish() }
|
|
110
148
|
async save() {
|
|
111
|
-
if (!this.dirty || this.saving || !this.snapshot().writable) return
|
|
112
|
-
const next = this.draftValue(), prev = this.value();
|
|
149
|
+
if (!this.dirty || this.saving || !this.snapshot().writable || this.snapshot().status !== "ready") return;
|
|
150
|
+
const next = this.draftValue(), prev = this.value();
|
|
151
|
+
const fields = FIELDS.filter((field) => next[field] !== prev[field]);
|
|
152
|
+
this.saving = true;
|
|
153
|
+
this.saveError = false;
|
|
154
|
+
this.publish();
|
|
113
155
|
try {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
156
|
+
if (fields.length) {
|
|
157
|
+
await this.scope.mutate(fields.map((field) => ({
|
|
158
|
+
op: "set",
|
|
159
|
+
path: [field],
|
|
160
|
+
value: next[field]
|
|
161
|
+
})));
|
|
162
|
+
if (this.snapshot().status !== "ready" || fields.some((field) => this.value()[field] !== next[field]))
|
|
163
|
+
throw new Error("Settings mutation was not confirmed");
|
|
164
|
+
}
|
|
165
|
+
this.draft = null;
|
|
166
|
+
this.dirty = false;
|
|
167
|
+
} catch {
|
|
168
|
+
this.saveError = true;
|
|
169
|
+
} finally {
|
|
170
|
+
this.saving = false;
|
|
171
|
+
this.publish();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
inject() {
|
|
175
|
+
return {
|
|
176
|
+
hooks: { lcxCard: this.store },
|
|
177
|
+
edit: (field, value) => this.edit(field, value),
|
|
178
|
+
save: () => void this.save(),
|
|
179
|
+
discard: () => this.discard()
|
|
180
|
+
};
|
|
117
181
|
}
|
|
118
|
-
inject() { return { hooks: { lcxCard: this.store }, edit: (f,v) => this.edit(f,v), save: () => void this.save(), discard: () => this.discard() } }
|
|
119
|
-
}
|
|
120
|
-
function Row({ id, label, help, checked, disabled, onChange }) {
|
|
121
|
-
return React.createElement('div', { className:'lcx-row' },
|
|
122
|
-
React.createElement('input', { id, type:'checkbox', checked, disabled, onChange:e=>onChange(e.target.checked) }),
|
|
123
|
-
React.createElement('label', { htmlFor:id }, label, React.createElement('small', null, help)))
|
|
124
182
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
183
|
+
function Row({
|
|
184
|
+
id,
|
|
185
|
+
label,
|
|
186
|
+
help,
|
|
187
|
+
checked,
|
|
188
|
+
disabled,
|
|
189
|
+
onChange
|
|
190
|
+
}) {
|
|
191
|
+
return React.createElement(
|
|
192
|
+
"div",
|
|
193
|
+
{ className: "lcx-row" },
|
|
194
|
+
React.createElement("input", {
|
|
195
|
+
id,
|
|
196
|
+
type: "checkbox",
|
|
197
|
+
checked,
|
|
198
|
+
disabled,
|
|
199
|
+
onChange: (event) => onChange(event.target.checked)
|
|
200
|
+
}),
|
|
201
|
+
React.createElement(
|
|
202
|
+
"label",
|
|
203
|
+
{ htmlFor: id },
|
|
204
|
+
label,
|
|
205
|
+
React.createElement("small", null, help)
|
|
206
|
+
)
|
|
207
|
+
);
|
|
130
208
|
}
|
|
131
209
|
function Card(props) {
|
|
132
|
-
const t =
|
|
133
|
-
if (!s.available) return null
|
|
134
|
-
const disabled = !s.writable || s.saving
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
React.createElement(
|
|
146
|
-
React.createElement(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
React.createElement(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
210
|
+
const t = props.t, s = props.useLcxCard((state) => state), [open, setOpen] = React.useState(false);
|
|
211
|
+
if (!s.available) return null;
|
|
212
|
+
const disabled = !s.writable || s.saving;
|
|
213
|
+
return React.createElement(
|
|
214
|
+
"li",
|
|
215
|
+
{ className: "lcx-card" },
|
|
216
|
+
React.createElement(
|
|
217
|
+
"button",
|
|
218
|
+
{
|
|
219
|
+
className: "lcx-head",
|
|
220
|
+
type: "button",
|
|
221
|
+
onClick: () => setOpen(!open)
|
|
222
|
+
},
|
|
223
|
+
React.createElement("strong", null, t("title")),
|
|
224
|
+
React.createElement("span", null, open ? "\u2303" : "\u2304")
|
|
225
|
+
),
|
|
226
|
+
open ? React.createElement(
|
|
227
|
+
"div",
|
|
228
|
+
{ className: "lcx-body" },
|
|
229
|
+
React.createElement("p", { className: "lcx-help" }, t("desc")),
|
|
230
|
+
React.createElement(Row, {
|
|
231
|
+
id: "lcx-enabled",
|
|
232
|
+
label: t("enabled"),
|
|
233
|
+
help: t("enabledHelp"),
|
|
234
|
+
checked: s.enabled.value,
|
|
235
|
+
disabled,
|
|
236
|
+
onChange: (value) => props.edit("enabled", value)
|
|
237
|
+
}),
|
|
238
|
+
React.createElement(Row, {
|
|
239
|
+
id: "lcx-web",
|
|
240
|
+
label: t("web"),
|
|
241
|
+
help: t("webHelp"),
|
|
242
|
+
checked: s.webSearch.value,
|
|
243
|
+
disabled: disabled || !s.enabled.value,
|
|
244
|
+
onChange: (value) => props.edit("webSearch", value)
|
|
245
|
+
}),
|
|
246
|
+
React.createElement(Row, {
|
|
247
|
+
id: "lcx-advanced",
|
|
248
|
+
label: t("advanced"),
|
|
249
|
+
help: t("advancedHelp"),
|
|
250
|
+
checked: s.advancedHostedSearch.value,
|
|
251
|
+
disabled: disabled || !s.enabled.value || !s.webSearch.value,
|
|
252
|
+
onChange: (value) => props.edit("advancedHostedSearch", value)
|
|
253
|
+
}),
|
|
254
|
+
React.createElement(Row, {
|
|
255
|
+
id: "lcx-alpha",
|
|
256
|
+
label: t("alpha"),
|
|
257
|
+
help: t("alphaHelp"),
|
|
258
|
+
checked: s.alphaSearch.value,
|
|
259
|
+
disabled: disabled || !s.enabled.value,
|
|
260
|
+
onChange: (value) => props.edit("alphaSearch", value)
|
|
261
|
+
}),
|
|
262
|
+
React.createElement(
|
|
263
|
+
"section",
|
|
264
|
+
{ className: "lcx-group" },
|
|
265
|
+
React.createElement("strong", null, t("grokTitle")),
|
|
266
|
+
React.createElement("p", { className: "lcx-help" }, t("grokDesc")),
|
|
267
|
+
React.createElement(Row, {
|
|
268
|
+
id: "lcx-grok-web",
|
|
269
|
+
label: t("grokWeb"),
|
|
270
|
+
help: t("grokWebHelp"),
|
|
271
|
+
checked: s.grokNativeWebSearch.value,
|
|
272
|
+
disabled,
|
|
273
|
+
onChange: (value) => props.edit("grokNativeWebSearch", value)
|
|
274
|
+
}),
|
|
275
|
+
React.createElement(Row, {
|
|
276
|
+
id: "lcx-grok-x",
|
|
277
|
+
label: t("grokX"),
|
|
278
|
+
help: t("grokXHelp"),
|
|
279
|
+
checked: s.grokNativeXSearch.value,
|
|
280
|
+
disabled,
|
|
281
|
+
onChange: (value) => props.edit("grokNativeXSearch", value)
|
|
282
|
+
})
|
|
283
|
+
),
|
|
284
|
+
React.createElement(
|
|
285
|
+
"p",
|
|
286
|
+
{ role: "alert", hidden: !s.saveError },
|
|
287
|
+
s.saveError ? t("saveError") : ""
|
|
288
|
+
),
|
|
289
|
+
React.createElement(
|
|
290
|
+
"div",
|
|
291
|
+
{ className: "lcx-foot" },
|
|
292
|
+
React.createElement(
|
|
293
|
+
"button",
|
|
294
|
+
{ disabled: !s.dirty || disabled, onClick: props.discard },
|
|
295
|
+
t("discard")
|
|
296
|
+
),
|
|
297
|
+
React.createElement(
|
|
298
|
+
"button",
|
|
299
|
+
{ disabled: !s.dirty || disabled, onClick: props.save },
|
|
300
|
+
s.saving ? t("saving") : t("save")
|
|
301
|
+
)
|
|
302
|
+
)
|
|
303
|
+
) : null
|
|
304
|
+
);
|
|
157
305
|
}
|
|
158
|
-
const inject = [
|
|
306
|
+
const inject = ["slots", "locale", "settingsScope"];
|
|
159
307
|
function apply(ctx) {
|
|
160
|
-
const slots = ctx.slots ?? ctx.get(
|
|
161
|
-
if (!slots || !svc) return
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
308
|
+
const slots = ctx.slots ?? ctx.get("slots"), svc = ctx.settingsScope ?? ctx.get("settingsScope"), locale = ctx.locale ?? ctx.get("locale");
|
|
309
|
+
if (!slots || !svc || !locale) return;
|
|
310
|
+
for (const language of ["zh", "en"])
|
|
311
|
+
ctx.effect(() => locale.register(NAMESPACE, language, copy[language]), `lcx-codex ${language} dictionary`);
|
|
312
|
+
const controller = new Controller(svc.bind({ namespace: NAMESPACE }));
|
|
313
|
+
slots.inject(
|
|
314
|
+
"settings.plugin.item",
|
|
315
|
+
() => slots.register(
|
|
316
|
+
{
|
|
317
|
+
name: "settings.plugin.item",
|
|
318
|
+
key: NAMESPACE,
|
|
319
|
+
locale: NAMESPACE,
|
|
320
|
+
inject: () => controller.inject()
|
|
321
|
+
},
|
|
322
|
+
Card
|
|
323
|
+
)
|
|
324
|
+
);
|
|
325
|
+
ctx.effect(() => () => controller.stop(), "lcx-codex settings card");
|
|
165
326
|
}
|
|
166
|
-
exports.apply = apply;
|
|
167
|
-
|
|
168
|
-
|
|
327
|
+
exports.apply = apply;
|
|
328
|
+
exports.inject = inject;
|
|
329
|
+
return module.exports;
|
|
330
|
+
}
|
|
331
|
+
});
|