codexmate 0.1.19 → 0.1.20
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/package.json +1 -1
- package/web-ui/modules/app.methods.navigation.mjs +2 -2
- package/web-ui/modules/app.methods.pi-config.mjs +10 -1
- package/web-ui/modules/i18n/locales/en.mjs +1 -1
- package/web-ui/modules/i18n/locales/ja.mjs +1 -1
- package/web-ui/modules/i18n/locales/vi.mjs +1 -1
- package/web-ui/modules/i18n/locales/zh-tw.mjs +1 -1
- package/web-ui/modules/i18n/locales/zh.mjs +1 -1
- package/web-ui/partials/index/panel-config-pi.html +23 -15
- package/web-ui/res/web-ui-render.precompiled.js +46 -39
- package/web-ui/session-helpers.mjs +23 -12
- package/web-ui/styles/controls-forms.css +7 -0
package/package.json
CHANGED
|
@@ -732,8 +732,8 @@
|
|
|
732
732
|
this.invalidateSessionTimelineMeasurementCache();
|
|
733
733
|
},
|
|
734
734
|
|
|
735
|
-
async loadMoreSessionMessages() {
|
|
736
|
-
return loadMoreSessionMessagesHelper.call(this);
|
|
735
|
+
async loadMoreSessionMessages(stepSize) {
|
|
736
|
+
return loadMoreSessionMessagesHelper.call(this, stepSize);
|
|
737
737
|
},
|
|
738
738
|
|
|
739
739
|
suspendSessionTabRender() {
|
|
@@ -55,6 +55,7 @@ export function createPiConfigMethods({ api: apiClient }) {
|
|
|
55
55
|
: '';
|
|
56
56
|
const updates = { defaultProvider: providerId };
|
|
57
57
|
if (firstModel) updates.defaultModel = firstModel;
|
|
58
|
+
else updates.defaultModel = '';
|
|
58
59
|
try {
|
|
59
60
|
const result = await apiClient('write-pi-settings', updates);
|
|
60
61
|
if (result && result.error) throw new Error(result.error);
|
|
@@ -126,6 +127,11 @@ export function createPiConfigMethods({ api: apiClient }) {
|
|
|
126
127
|
this.messageType = 'error';
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
130
|
+
if (!Array.isArray(merged.models) || merged.models.length === 0) {
|
|
131
|
+
this.message = '请至少导入或输入一个模型';
|
|
132
|
+
this.messageType = 'error';
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
129
135
|
const providerId = isNew ? this.derivePiProviderId(baseUrl) : editor.id;
|
|
130
136
|
if (isNew) {
|
|
131
137
|
merged.id = providerId;
|
|
@@ -207,6 +213,7 @@ export function createPiConfigMethods({ api: apiClient }) {
|
|
|
207
213
|
startPiProviderDraft(tpl) {
|
|
208
214
|
const template = isPiPlainObject(tpl) ? tpl : {};
|
|
209
215
|
this.resetPiEditorTransientState();
|
|
216
|
+
this.showAddPiProviderModal = false;
|
|
210
217
|
this.editingPiProvider = {
|
|
211
218
|
id: '',
|
|
212
219
|
isNew: true,
|
|
@@ -350,6 +357,8 @@ export function createPiConfigMethods({ api: apiClient }) {
|
|
|
350
357
|
const wasNew = !!editor.isNew;
|
|
351
358
|
this.resetPiProviderEditing();
|
|
352
359
|
if (wasNew) this.piSelectedProviderTemplate = '';
|
|
360
|
+
this.showAddPiProviderModal = false;
|
|
361
|
+
this.piProviderPickerQuery = '';
|
|
353
362
|
},
|
|
354
363
|
removePiProviderModel(index) {
|
|
355
364
|
if (!this.editingPiProvider) return;
|
|
@@ -544,7 +553,7 @@ export function createPiConfigMethods({ api: apiClient }) {
|
|
|
544
553
|
if (merged.baseUrl === undefined) merged.baseUrl = values.baseUrl || '';
|
|
545
554
|
if (merged.api === undefined) merged.api = values.api || '';
|
|
546
555
|
if (merged.apiKey === undefined) merged.apiKey = values.apiKey || '';
|
|
547
|
-
|
|
556
|
+
merged.models = mapModels(merged.models !== undefined ? merged.models : values.models);
|
|
548
557
|
if (isPiPlainObject(orig.headers)) merged.headers = orig.headers;
|
|
549
558
|
if (typeof orig.title === 'string') merged.title = orig.title;
|
|
550
559
|
else if (typeof orig.name === 'string') merged.name = orig.name;
|
|
@@ -1362,9 +1362,9 @@ const en = Object.freeze({
|
|
|
1362
1362
|
'pi.providers.json.previewTitle': 'Preview',
|
|
1363
1363
|
'pi.providers.json.editTitle': 'Edit JSON',
|
|
1364
1364
|
'pi.files.title': 'File JSON',
|
|
1365
|
-
'pi.files.desc': 'View and edit Pi settings.json and models.json in full; JSON validity is checked before saving and invalid content is never written.',
|
|
1366
1365
|
'pi.files.settingsTitle': 'settings.json (active settings)',
|
|
1367
1366
|
'pi.files.modelsTitle': 'models.json (providers and models)',
|
|
1367
|
+
'pi.files.modelsHint': 'Merged automatically from the provider management above; prefer editing providers there instead.',
|
|
1368
1368
|
'pi.history.apply': 'Apply this record',
|
|
1369
1369
|
'pi.history.applied': 'History record applied',
|
|
1370
1370
|
'pi.history.applyFailed': 'Failed to apply history record',
|
|
@@ -1363,9 +1363,9 @@ const ja = Object.freeze({
|
|
|
1363
1363
|
'pi.providers.json.previewTitle': 'プレビュー',
|
|
1364
1364
|
'pi.providers.json.editTitle': 'JSON を編集',
|
|
1365
1365
|
'pi.files.title': 'ファイル JSON',
|
|
1366
|
-
'pi.files.desc': 'Pi の settings.json と models.json を全文表示して直接編集します。保存前に JSON の正当性を検証し、不正な内容は書き込みません。',
|
|
1367
1366
|
'pi.files.settingsTitle': 'settings.json(有効な設定)',
|
|
1368
1367
|
'pi.files.modelsTitle': 'models.json(プロバイダーとモデル)',
|
|
1368
|
+
'pi.files.modelsHint': '上のプロバイダー管理から自動的にマージされます。プロバイダーの変更は上の管理画面を優先してください。',
|
|
1369
1369
|
'pi.history.apply': 'この履歴を適用',
|
|
1370
1370
|
'pi.history.applied': '履歴を適用しました',
|
|
1371
1371
|
'pi.history.applyFailed': '履歴の適用に失敗しました',
|
|
@@ -1331,9 +1331,9 @@ const vi = Object.freeze({
|
|
|
1331
1331
|
'pi.providers.json.previewTitle': 'Xem trước',
|
|
1332
1332
|
'pi.providers.json.editTitle': 'Chỉnh sửa JSON',
|
|
1333
1333
|
'pi.files.title': 'JSON tập tin',
|
|
1334
|
-
'pi.files.desc': 'Hiển thị đầy đủ và chỉnh sửa trực tiếp settings.json và models.json của Pi; kiểm tra tính hợp lệ của JSON trước khi lưu, nội dung không hợp lệ sẽ không được ghi.',
|
|
1335
1334
|
'pi.files.settingsTitle': 'settings.json (cài đặt đang dùng)',
|
|
1336
1335
|
'pi.files.modelsTitle': 'models.json (nhà cung cấp và mô hình)',
|
|
1336
|
+
'pi.files.modelsHint': 'Được hợp nhất tự động từ phần quản lý nhà cung cấp phía trên; hãy ưu tiên chỉnh sửa ở đó.',
|
|
1337
1337
|
'pi.history.apply': 'Áp dụng bản ghi này',
|
|
1338
1338
|
'pi.history.applied': 'Đã áp dụng lịch sử',
|
|
1339
1339
|
'pi.history.applyFailed': 'Áp dụng lịch sử thất bại',
|
|
@@ -1360,9 +1360,9 @@ const zhTw = Object.freeze({
|
|
|
1360
1360
|
'pi.providers.json.previewTitle': '預覽',
|
|
1361
1361
|
'pi.providers.json.editTitle': '編輯 JSON',
|
|
1362
1362
|
'pi.files.title': '檔案 JSON',
|
|
1363
|
-
'pi.files.desc': '完整展示並直接編輯 Pi 的 settings.json 與 models.json;儲存前校驗 JSON 合法性,非法內容不會寫入。',
|
|
1364
1363
|
'pi.files.settingsTitle': 'settings.json(生效設定)',
|
|
1365
1364
|
'pi.files.modelsTitle': 'models.json(供應商與模型)',
|
|
1365
|
+
'pi.files.modelsHint': '由上方供應商管理自動合併生成;調整供應商請優先使用上方的供應商管理。',
|
|
1366
1366
|
'pi.history.apply': '套用此紀錄',
|
|
1367
1367
|
'pi.history.applied': '已套用歷史紀錄',
|
|
1368
1368
|
'pi.history.applyFailed': '套用歷史紀錄失敗',
|
|
@@ -1360,9 +1360,9 @@ const zh = Object.freeze({
|
|
|
1360
1360
|
'pi.providers.json.previewTitle': '预览',
|
|
1361
1361
|
'pi.providers.json.editTitle': '编辑 JSON',
|
|
1362
1362
|
'pi.files.title': '文件 JSON',
|
|
1363
|
-
'pi.files.desc': '完整展示并直接编辑 Pi 的 settings.json 与 models.json;保存前校验 JSON 合法性,非法内容不会写入。',
|
|
1364
1363
|
'pi.files.settingsTitle': 'settings.json(生效设置)',
|
|
1365
1364
|
'pi.files.modelsTitle': 'models.json(供应商与模型)',
|
|
1365
|
+
'pi.files.modelsHint': '由上方供应商管理自动合并生成;调整供应商请优先使用上方的供应商管理。',
|
|
1366
1366
|
'pi.history.apply': '应用此记录',
|
|
1367
1367
|
'pi.history.applied': '已应用历史记录',
|
|
1368
1368
|
'pi.history.applyFailed': '应用历史记录失败',
|
|
@@ -49,19 +49,24 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
<div class="card-trailing">
|
|
51
51
|
<span v-if="piActiveProvider === providerId" class="pill configured">{{ t('pi.providers.active') }}</span>
|
|
52
|
-
<button v-else type="button" class="btn-tool" @click.stop="switchPiActiveProvider(providerId)" :disabled="!isToolConfigWriteAllowed('pi') || piSaving">{{ t('pi.providers.setActive') }}</button>
|
|
52
|
+
<button v-else type="button" class="btn-tool btn-tool-compact" @click.stop="switchPiActiveProvider(providerId)" :disabled="!isToolConfigWriteAllowed('pi') || piSaving">{{ t('pi.providers.setActive') }}</button>
|
|
53
53
|
</div>
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
56
|
-
<div v-if="!piProviderIds.length" class="
|
|
56
|
+
<div v-if="!piProviderIds.length" class="empty-state">
|
|
57
|
+
<div class="empty-state-title">{{ t('pi.providers.empty') }}</div>
|
|
58
|
+
</div>
|
|
57
59
|
</section>
|
|
58
60
|
|
|
59
|
-
<section class="selector-section">
|
|
61
|
+
<section class="selector-section pi-file-section">
|
|
60
62
|
<div class="selector-header">
|
|
61
|
-
<span class="selector-title">{{ t('pi.files.
|
|
63
|
+
<span class="selector-title">{{ t('pi.files.settingsTitle') }}</span>
|
|
64
|
+
<div class="selector-actions">
|
|
65
|
+
<button type="button" class="btn-tool btn-tool-compact" @click="openPiConfigHistory('settings')" :disabled="piHistoryLoading">{{ t('common.history') }}</button>
|
|
66
|
+
<button type="button" class="btn-tool btn-tool-compact" @click="savePiSettingsJson" :disabled="!isToolConfigWriteAllowed('pi') || piSaving || piFileJsonSaving || !!piSettingsJsonError">{{ t('common.save') }}</button>
|
|
67
|
+
</div>
|
|
62
68
|
</div>
|
|
63
|
-
<div class="config-template-hint">{{ t('pi.
|
|
64
|
-
<label class="form-label">{{ t('pi.files.settingsTitle') }}</label>
|
|
69
|
+
<div class="config-template-hint">{{ t('pi.providers.targetFile', { path: '~/.pi/agent/settings.json' }) }}</div>
|
|
65
70
|
<textarea
|
|
66
71
|
class="template-textarea config-json-editor"
|
|
67
72
|
v-model="piSettingsJsonDraft"
|
|
@@ -71,10 +76,6 @@
|
|
|
71
76
|
@input="piSettingsJsonInput"
|
|
72
77
|
placeholder="{}"></textarea>
|
|
73
78
|
<p v-if="piSettingsJsonError" class="config-template-hint error-text">{{ piSettingsJsonError }}</p>
|
|
74
|
-
<div class="settings-tab-actions">
|
|
75
|
-
<button type="button" class="btn-tool" @click="savePiSettingsJson" :disabled="!isToolConfigWriteAllowed('pi') || piSaving || piFileJsonSaving || !!piSettingsJsonError">{{ t('common.save') }}</button>
|
|
76
|
-
<button type="button" class="btn-mini" @click="openPiConfigHistory('settings')" :disabled="piHistoryLoading">{{ t('common.history') }}</button>
|
|
77
|
-
</div>
|
|
78
79
|
<details v-if="piHistoryTarget === 'settings'" class="prompt-history-panel" open>
|
|
79
80
|
<summary class="prompt-history-summary">
|
|
80
81
|
<span>{{ t('common.history') }}</span>
|
|
@@ -96,7 +97,18 @@
|
|
|
96
97
|
</div>
|
|
97
98
|
</div>
|
|
98
99
|
</details>
|
|
99
|
-
|
|
100
|
+
</section>
|
|
101
|
+
|
|
102
|
+
<section class="selector-section pi-file-section">
|
|
103
|
+
<div class="selector-header">
|
|
104
|
+
<span class="selector-title">{{ t('pi.files.modelsTitle') }}</span>
|
|
105
|
+
<div class="selector-actions">
|
|
106
|
+
<button type="button" class="btn-tool btn-tool-compact" @click="openPiConfigHistory('models')" :disabled="piHistoryLoading">{{ t('common.history') }}</button>
|
|
107
|
+
<button type="button" class="btn-tool btn-tool-compact" @click="savePiModelsJson" :disabled="!isToolConfigWriteAllowed('pi') || piSaving || piFileJsonSaving || !!piModelsJsonError">{{ t('common.save') }}</button>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="config-template-hint">{{ t('pi.files.modelsHint') }}</div>
|
|
111
|
+
<div class="config-template-hint">{{ t('pi.providers.targetFile', { path: '~/.pi/agent/models.json' }) }}</div>
|
|
100
112
|
<textarea
|
|
101
113
|
class="template-textarea config-json-editor"
|
|
102
114
|
v-model="piModelsJsonDraft"
|
|
@@ -106,10 +118,6 @@
|
|
|
106
118
|
@input="piModelsJsonInput"
|
|
107
119
|
placeholder="{}"></textarea>
|
|
108
120
|
<p v-if="piModelsJsonError" class="config-template-hint error-text">{{ piModelsJsonError }}</p>
|
|
109
|
-
<div class="settings-tab-actions">
|
|
110
|
-
<button type="button" class="btn-tool" @click="savePiModelsJson" :disabled="!isToolConfigWriteAllowed('pi') || piSaving || piFileJsonSaving || !!piModelsJsonError">{{ t('common.save') }}</button>
|
|
111
|
-
<button type="button" class="btn-mini" @click="openPiConfigHistory('models')" :disabled="piHistoryLoading">{{ t('common.history') }}</button>
|
|
112
|
-
</div>
|
|
113
121
|
<details v-if="piHistoryTarget === 'models'" class="prompt-history-panel" open>
|
|
114
122
|
<summary class="prompt-history-summary">
|
|
115
123
|
<span>{{ t('common.history') }}</span>
|
|
@@ -3268,7 +3268,7 @@ return function render(_ctx, _cache) {
|
|
|
3268
3268
|
: (_openBlock(), _createElementBlock("button", {
|
|
3269
3269
|
key: 1,
|
|
3270
3270
|
type: "button",
|
|
3271
|
-
class: "btn-tool",
|
|
3271
|
+
class: "btn-tool btn-tool-compact",
|
|
3272
3272
|
onClick: _withModifiers($event => (_ctx.switchPiActiveProvider(providerId)), ["stop"]),
|
|
3273
3273
|
disabled: !_ctx.isToolConfigWriteAllowed('pi') || _ctx.piSaving
|
|
3274
3274
|
}, _toDisplayString(_ctx.t('pi.providers.setActive')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]))
|
|
@@ -3280,16 +3280,31 @@ return function render(_ctx, _cache) {
|
|
|
3280
3280
|
(!_ctx.piProviderIds.length)
|
|
3281
3281
|
? (_openBlock(), _createElementBlock("div", {
|
|
3282
3282
|
key: 1,
|
|
3283
|
-
class: "
|
|
3284
|
-
},
|
|
3283
|
+
class: "empty-state"
|
|
3284
|
+
}, [
|
|
3285
|
+
_createElementVNode("div", { class: "empty-state-title" }, _toDisplayString(_ctx.t('pi.providers.empty')), 1 /* TEXT */)
|
|
3286
|
+
]))
|
|
3285
3287
|
: _createCommentVNode("v-if", true)
|
|
3286
3288
|
]),
|
|
3287
|
-
_createElementVNode("section", { class: "selector-section" }, [
|
|
3289
|
+
_createElementVNode("section", { class: "selector-section pi-file-section" }, [
|
|
3288
3290
|
_createElementVNode("div", { class: "selector-header" }, [
|
|
3289
|
-
_createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('pi.files.
|
|
3291
|
+
_createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('pi.files.settingsTitle')), 1 /* TEXT */),
|
|
3292
|
+
_createElementVNode("div", { class: "selector-actions" }, [
|
|
3293
|
+
_createElementVNode("button", {
|
|
3294
|
+
type: "button",
|
|
3295
|
+
class: "btn-tool btn-tool-compact",
|
|
3296
|
+
onClick: $event => (_ctx.openPiConfigHistory('settings')),
|
|
3297
|
+
disabled: _ctx.piHistoryLoading
|
|
3298
|
+
}, _toDisplayString(_ctx.t('common.history')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
|
|
3299
|
+
_createElementVNode("button", {
|
|
3300
|
+
type: "button",
|
|
3301
|
+
class: "btn-tool btn-tool-compact",
|
|
3302
|
+
onClick: _ctx.savePiSettingsJson,
|
|
3303
|
+
disabled: !_ctx.isToolConfigWriteAllowed('pi') || _ctx.piSaving || _ctx.piFileJsonSaving || !!_ctx.piSettingsJsonError
|
|
3304
|
+
}, _toDisplayString(_ctx.t('common.save')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
|
|
3305
|
+
])
|
|
3290
3306
|
]),
|
|
3291
|
-
_createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('pi.
|
|
3292
|
-
_createElementVNode("label", { class: "form-label" }, _toDisplayString(_ctx.t('pi.files.settingsTitle')), 1 /* TEXT */),
|
|
3307
|
+
_createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('pi.providers.targetFile', { path: '~/.pi/agent/settings.json' })), 1 /* TEXT */),
|
|
3293
3308
|
_withDirectives(_createElementVNode("textarea", {
|
|
3294
3309
|
class: "template-textarea config-json-editor",
|
|
3295
3310
|
"onUpdate:modelValue": $event => ((_ctx.piSettingsJsonDraft) = $event),
|
|
@@ -3307,20 +3322,6 @@ return function render(_ctx, _cache) {
|
|
|
3307
3322
|
class: "config-template-hint error-text"
|
|
3308
3323
|
}, _toDisplayString(_ctx.piSettingsJsonError), 1 /* TEXT */))
|
|
3309
3324
|
: _createCommentVNode("v-if", true),
|
|
3310
|
-
_createElementVNode("div", { class: "settings-tab-actions" }, [
|
|
3311
|
-
_createElementVNode("button", {
|
|
3312
|
-
type: "button",
|
|
3313
|
-
class: "btn-tool",
|
|
3314
|
-
onClick: _ctx.savePiSettingsJson,
|
|
3315
|
-
disabled: !_ctx.isToolConfigWriteAllowed('pi') || _ctx.piSaving || _ctx.piFileJsonSaving || !!_ctx.piSettingsJsonError
|
|
3316
|
-
}, _toDisplayString(_ctx.t('common.save')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
|
|
3317
|
-
_createElementVNode("button", {
|
|
3318
|
-
type: "button",
|
|
3319
|
-
class: "btn-mini",
|
|
3320
|
-
onClick: $event => (_ctx.openPiConfigHistory('settings')),
|
|
3321
|
-
disabled: _ctx.piHistoryLoading
|
|
3322
|
-
}, _toDisplayString(_ctx.t('common.history')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
|
|
3323
|
-
]),
|
|
3324
3325
|
(_ctx.piHistoryTarget === 'settings')
|
|
3325
3326
|
? (_openBlock(), _createElementBlock("details", {
|
|
3326
3327
|
key: 1,
|
|
@@ -3386,8 +3387,28 @@ return function render(_ctx, _cache) {
|
|
|
3386
3387
|
: _createCommentVNode("v-if", true)
|
|
3387
3388
|
])
|
|
3388
3389
|
]))
|
|
3389
|
-
: _createCommentVNode("v-if", true)
|
|
3390
|
-
|
|
3390
|
+
: _createCommentVNode("v-if", true)
|
|
3391
|
+
]),
|
|
3392
|
+
_createElementVNode("section", { class: "selector-section pi-file-section" }, [
|
|
3393
|
+
_createElementVNode("div", { class: "selector-header" }, [
|
|
3394
|
+
_createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('pi.files.modelsTitle')), 1 /* TEXT */),
|
|
3395
|
+
_createElementVNode("div", { class: "selector-actions" }, [
|
|
3396
|
+
_createElementVNode("button", {
|
|
3397
|
+
type: "button",
|
|
3398
|
+
class: "btn-tool btn-tool-compact",
|
|
3399
|
+
onClick: $event => (_ctx.openPiConfigHistory('models')),
|
|
3400
|
+
disabled: _ctx.piHistoryLoading
|
|
3401
|
+
}, _toDisplayString(_ctx.t('common.history')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
|
|
3402
|
+
_createElementVNode("button", {
|
|
3403
|
+
type: "button",
|
|
3404
|
+
class: "btn-tool btn-tool-compact",
|
|
3405
|
+
onClick: _ctx.savePiModelsJson,
|
|
3406
|
+
disabled: !_ctx.isToolConfigWriteAllowed('pi') || _ctx.piSaving || _ctx.piFileJsonSaving || !!_ctx.piModelsJsonError
|
|
3407
|
+
}, _toDisplayString(_ctx.t('common.save')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
|
|
3408
|
+
])
|
|
3409
|
+
]),
|
|
3410
|
+
_createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('pi.files.modelsHint')), 1 /* TEXT */),
|
|
3411
|
+
_createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('pi.providers.targetFile', { path: '~/.pi/agent/models.json' })), 1 /* TEXT */),
|
|
3391
3412
|
_withDirectives(_createElementVNode("textarea", {
|
|
3392
3413
|
class: "template-textarea config-json-editor",
|
|
3393
3414
|
"onUpdate:modelValue": $event => ((_ctx.piModelsJsonDraft) = $event),
|
|
@@ -3401,27 +3422,13 @@ return function render(_ctx, _cache) {
|
|
|
3401
3422
|
]),
|
|
3402
3423
|
(_ctx.piModelsJsonError)
|
|
3403
3424
|
? (_openBlock(), _createElementBlock("p", {
|
|
3404
|
-
key:
|
|
3425
|
+
key: 0,
|
|
3405
3426
|
class: "config-template-hint error-text"
|
|
3406
3427
|
}, _toDisplayString(_ctx.piModelsJsonError), 1 /* TEXT */))
|
|
3407
3428
|
: _createCommentVNode("v-if", true),
|
|
3408
|
-
_createElementVNode("div", { class: "settings-tab-actions" }, [
|
|
3409
|
-
_createElementVNode("button", {
|
|
3410
|
-
type: "button",
|
|
3411
|
-
class: "btn-tool",
|
|
3412
|
-
onClick: _ctx.savePiModelsJson,
|
|
3413
|
-
disabled: !_ctx.isToolConfigWriteAllowed('pi') || _ctx.piSaving || _ctx.piFileJsonSaving || !!_ctx.piModelsJsonError
|
|
3414
|
-
}, _toDisplayString(_ctx.t('common.save')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
|
|
3415
|
-
_createElementVNode("button", {
|
|
3416
|
-
type: "button",
|
|
3417
|
-
class: "btn-mini",
|
|
3418
|
-
onClick: $event => (_ctx.openPiConfigHistory('models')),
|
|
3419
|
-
disabled: _ctx.piHistoryLoading
|
|
3420
|
-
}, _toDisplayString(_ctx.t('common.history')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
|
|
3421
|
-
]),
|
|
3422
3429
|
(_ctx.piHistoryTarget === 'models')
|
|
3423
3430
|
? (_openBlock(), _createElementBlock("details", {
|
|
3424
|
-
key:
|
|
3431
|
+
key: 1,
|
|
3425
3432
|
class: "prompt-history-panel",
|
|
3426
3433
|
open: ""
|
|
3427
3434
|
}, [
|
|
@@ -530,7 +530,7 @@ export async function loadActiveSessionDetail(api, options = {}) {
|
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
532
|
|
|
533
|
-
export async function loadMoreSessionMessages() {
|
|
533
|
+
export async function loadMoreSessionMessages(stepSize) {
|
|
534
534
|
if (this.mainTab !== 'sessions' || !this.sessionPreviewRenderEnabled) {
|
|
535
535
|
return;
|
|
536
536
|
}
|
|
@@ -541,6 +541,19 @@ export async function loadMoreSessionMessages() {
|
|
|
541
541
|
this.sessionPreviewVisibleCount = 0;
|
|
542
542
|
return;
|
|
543
543
|
}
|
|
544
|
+
const step = Number.isFinite(stepSize)
|
|
545
|
+
? Math.max(1, Math.floor(stepSize))
|
|
546
|
+
: (Number.isFinite(this.sessionPreviewLoadStep)
|
|
547
|
+
? Math.max(1, Math.floor(this.sessionPreviewLoadStep))
|
|
548
|
+
: 40);
|
|
549
|
+
const current = Number.isFinite(this.sessionPreviewVisibleCount)
|
|
550
|
+
? Math.max(0, Math.floor(this.sessionPreviewVisibleCount))
|
|
551
|
+
: 0;
|
|
552
|
+
const targetVisible = current + step;
|
|
553
|
+
if (targetVisible <= total) {
|
|
554
|
+
this.sessionPreviewVisibleCount = Math.min(total, targetVisible);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
544
557
|
|
|
545
558
|
this.sessionPreviewVisibleCount = total;
|
|
546
559
|
if (this.sessionDetailLoading) {
|
|
@@ -560,19 +573,24 @@ export async function loadMoreSessionMessages() {
|
|
|
560
573
|
const currentLimit = Number.isFinite(currentLimitRaw)
|
|
561
574
|
? Math.max(1, Math.floor(currentLimitRaw))
|
|
562
575
|
: Math.max(1, total);
|
|
576
|
+
const fetchStep = Number.isFinite(this.sessionDetailFetchStep)
|
|
577
|
+
? Math.max(1, Math.floor(this.sessionDetailFetchStep))
|
|
578
|
+
: 80;
|
|
563
579
|
const limitCapRaw = Number(this.sessionDetailMessageLimitCap);
|
|
564
580
|
const limitCap = Number.isFinite(limitCapRaw)
|
|
565
581
|
? Math.max(1, Math.floor(limitCapRaw))
|
|
566
582
|
: 1000;
|
|
567
583
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
584
|
+
let nextLimit = Math.max(currentLimit + fetchStep, targetVisible);
|
|
585
|
+
if (totalKnown > total) {
|
|
586
|
+
nextLimit = Math.min(nextLimit, totalKnown);
|
|
587
|
+
}
|
|
588
|
+
nextLimit = Math.min(nextLimit, limitCap);
|
|
571
589
|
if (nextLimit <= currentLimit) {
|
|
572
590
|
return;
|
|
573
591
|
}
|
|
574
592
|
|
|
575
|
-
this.sessionPreviewPendingVisibleCount =
|
|
593
|
+
this.sessionPreviewPendingVisibleCount = targetVisible;
|
|
576
594
|
this.sessionDetailMessageLimit = nextLimit;
|
|
577
595
|
this.sessionPreviewLoadingMore = true;
|
|
578
596
|
try {
|
|
@@ -580,11 +598,4 @@ export async function loadMoreSessionMessages() {
|
|
|
580
598
|
} finally {
|
|
581
599
|
this.sessionPreviewLoadingMore = false;
|
|
582
600
|
}
|
|
583
|
-
|
|
584
|
-
const loadedTotal = Array.isArray(this.activeSessionMessages)
|
|
585
|
-
? this.activeSessionMessages.length
|
|
586
|
-
: 0;
|
|
587
|
-
if (loadedTotal > this.sessionPreviewVisibleCount) {
|
|
588
|
-
this.sessionPreviewVisibleCount = loadedTotal;
|
|
589
|
-
}
|
|
590
601
|
}
|
|
@@ -104,6 +104,13 @@
|
|
|
104
104
|
flex: 0 0 auto;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
.selector-header .selector-actions > .btn-tool + .btn-tool,
|
|
108
|
+
.selector-header .selector-actions > .btn-tool-compact + .btn-tool,
|
|
109
|
+
.selector-header .selector-actions > .btn-tool + .btn-tool-compact,
|
|
110
|
+
.selector-header .selector-actions > .btn-tool-compact + .btn-tool-compact {
|
|
111
|
+
margin-top: 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
107
114
|
.selector-actions.opencode-provider-actions {
|
|
108
115
|
display: inline-flex;
|
|
109
116
|
align-items: stretch;
|