@hachej/boring-agent 0.1.103 → 0.1.104
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/dist/{chunk-7QM22DU7.js → chunk-6DRHERVK.js} +7 -5
- package/dist/{chunk-6WKQ4FC4.js → chunk-BTYOMR7W.js} +52 -8
- package/dist/{chunk-TW7G33QH.js → chunk-I7KFNGB4.js} +27 -1
- package/dist/core/index.d.ts +5 -5
- package/dist/{createHarness-4Q6DQBRT.js → createHarness-POZ4AXCZ.js} +1 -1
- package/dist/{errors-szpcDUFQ.d.ts → errors-DH7C01Pm.d.ts} +1 -1
- package/dist/{file-search-BXdSm-Yq.d.ts → file-search-qcD5zItr.d.ts} +3 -3
- package/dist/front/index.d.ts +5 -2
- package/dist/front/index.js +183 -130
- package/dist/front/styles.css +4 -0
- package/dist/{harness-erpL2SER.d.ts → harness-Dcd08yKr.d.ts} +1 -1
- package/dist/{lease-K-EZhdL-.d.ts → lease-DffrPrQn.d.ts} +1 -1
- package/dist/{piChatEvent-g1nIBh44.d.ts → piChatEvent-iNSXiFQq.d.ts} +5 -0
- package/dist/{piChatSessionService-DugeRHzb.d.ts → piChatSessionService-DQSQ_kWZ.d.ts} +1 -1
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +5 -5
- package/dist/server/agent-host/testing/gatewayConformance.js +1 -1
- package/dist/server/index.d.ts +12 -10
- package/dist/server/index.js +3 -3
- package/dist/server/worker/index.js +3 -3
- package/dist/shared/index.d.ts +93 -19
- package/dist/shared/index.js +1 -1
- package/dist/{types-BnjMLAd5.d.ts → types-B1xDlBSo.d.ts} +4 -4
- package/package.json +4 -4
package/dist/front/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
WORKSPACE_COMMAND_NOTIFY_EVENT,
|
|
32
32
|
extractToolUiMetadata,
|
|
33
33
|
sanitizeToolUiMetadata
|
|
34
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-6DRHERVK.js";
|
|
35
35
|
import "../chunk-YGRQ4Q5P.js";
|
|
36
36
|
import {
|
|
37
37
|
ErrorCode
|
|
@@ -85,7 +85,7 @@ function rawWorkspaceFileUrl(path, opts) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// src/front/chat/PiChatPanel.tsx
|
|
88
|
-
import { lazy, Suspense, useCallback as useCallback18, useEffect as useEffect21, useMemo as useMemo16, useRef as
|
|
88
|
+
import { lazy, Suspense, useCallback as useCallback18, useEffect as useEffect21, useMemo as useMemo16, useRef as useRef17, useState as useState20 } from "react";
|
|
89
89
|
|
|
90
90
|
// src/front/chatPanelSettings.ts
|
|
91
91
|
var DEFAULT_THINKING = "medium";
|
|
@@ -2126,7 +2126,7 @@ function useComposerPickers({
|
|
|
2126
2126
|
}
|
|
2127
2127
|
|
|
2128
2128
|
// src/front/hooks/useChatModelSelection.ts
|
|
2129
|
-
import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo2,
|
|
2129
|
+
import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo2, useState as useState7 } from "react";
|
|
2130
2130
|
|
|
2131
2131
|
// src/front/browserFiles.ts
|
|
2132
2132
|
var convertBlobUrlToDataUrl = async (url) => {
|
|
@@ -2550,35 +2550,59 @@ function resolveStorage(storage) {
|
|
|
2550
2550
|
}
|
|
2551
2551
|
|
|
2552
2552
|
// src/front/hooks/useChatModelSelection.ts
|
|
2553
|
+
function sameModel(left, right) {
|
|
2554
|
+
return left?.provider === right?.provider && left?.id === right?.id;
|
|
2555
|
+
}
|
|
2556
|
+
function availableModel(models, model) {
|
|
2557
|
+
return Boolean(model && models.some((candidate) => candidate.available && candidate.provider === model.provider && candidate.id === model.id));
|
|
2558
|
+
}
|
|
2553
2559
|
function useChatModelSelection({
|
|
2554
2560
|
agentTypeId,
|
|
2555
2561
|
apiBaseUrl,
|
|
2556
2562
|
defaultModel,
|
|
2563
|
+
sessionId,
|
|
2564
|
+
sessionHydrated = sessionId === void 0,
|
|
2565
|
+
sessionIsNew = sessionId === void 0,
|
|
2566
|
+
sessionModel,
|
|
2557
2567
|
fetch: fetchImpl,
|
|
2558
2568
|
requestHeaders,
|
|
2559
2569
|
storage,
|
|
2560
2570
|
storageScope,
|
|
2561
2571
|
enabled = true
|
|
2562
2572
|
}) {
|
|
2563
|
-
const
|
|
2564
|
-
const [
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
);
|
|
2570
|
-
const userSelectedModelRef = useRef6(userSelectedModel);
|
|
2571
|
-
const loadedSettingsSourceRef = useRef6({ storage, storageScope });
|
|
2573
|
+
const initialSettings = useMemo2(() => readPiComposerSettings({ storageScope, storage }), []);
|
|
2574
|
+
const [selection, setSelection] = useState7(() => ({
|
|
2575
|
+
sessionId,
|
|
2576
|
+
storage,
|
|
2577
|
+
storageScope,
|
|
2578
|
+
localDefault: initialSettings.model ?? defaultModel ?? null
|
|
2579
|
+
}));
|
|
2572
2580
|
useEffect5(() => {
|
|
2573
|
-
|
|
2574
|
-
|
|
2581
|
+
const settings = readPiComposerSettings({ storageScope, storage });
|
|
2582
|
+
setSelection((current) => {
|
|
2583
|
+
const sameSession = current.sessionId === sessionId;
|
|
2584
|
+
const pendingOverride2 = sameSession && current.pendingOverride && sessionModel && !sameModel(current.pendingOverride, sessionModel) ? current.pendingOverride : sessionIsNew && sessionModel && settings.model && !sameModel(settings.model, sessionModel) ? settings.model : void 0;
|
|
2585
|
+
return {
|
|
2586
|
+
sessionId,
|
|
2587
|
+
storage,
|
|
2588
|
+
storageScope,
|
|
2589
|
+
localDefault: settings.model ?? defaultModel ?? null,
|
|
2590
|
+
...pendingOverride2 ? { pendingOverride: pendingOverride2 } : {}
|
|
2591
|
+
};
|
|
2592
|
+
});
|
|
2593
|
+
}, [defaultModel, sessionId, sessionIsNew, sessionModel?.id, sessionModel?.provider, storage, storageScope]);
|
|
2575
2594
|
const setModel = useCallback6((next) => {
|
|
2576
2595
|
const normalized = next === null ? null : parseModelSelection(next);
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2596
|
+
setSelection((current) => {
|
|
2597
|
+
if (sessionModel) {
|
|
2598
|
+
const pendingOverride2 = normalized && !sameModel(normalized, sessionModel) ? normalized : void 0;
|
|
2599
|
+
return { ...current, sessionId, ...pendingOverride2 ? { pendingOverride: pendingOverride2 } : { pendingOverride: void 0 } };
|
|
2600
|
+
}
|
|
2601
|
+
if (sessionId && !sessionIsNew) return current;
|
|
2602
|
+
return { ...current, sessionId, localDefault: normalized, pendingOverride: void 0 };
|
|
2603
|
+
});
|
|
2580
2604
|
writePiComposerModelSelection(normalized, { storageScope, storage });
|
|
2581
|
-
}, [storage, storageScope]);
|
|
2605
|
+
}, [sessionId, sessionIsNew, sessionModel, storage, storageScope]);
|
|
2582
2606
|
const discoveryKey = useMemo2(
|
|
2583
2607
|
() => JSON.stringify({
|
|
2584
2608
|
apiBaseUrl: apiBaseUrl ?? "",
|
|
@@ -2591,22 +2615,6 @@ function useChatModelSelection({
|
|
|
2591
2615
|
const [availableModels, setAvailableModels] = useState7([]);
|
|
2592
2616
|
const [loaded, setLoaded] = useState7(!enabled);
|
|
2593
2617
|
const [loadedDiscoveryKey, setLoadedDiscoveryKey] = useState7(enabled ? null : discoveryKey);
|
|
2594
|
-
useEffect5(() => {
|
|
2595
|
-
if (loadedSettingsSourceRef.current.storage !== storage || loadedSettingsSourceRef.current.storageScope !== storageScope) return;
|
|
2596
|
-
if (!userSelectedModel || !model) return;
|
|
2597
|
-
writePiComposerModelSelection(model, { storageScope, storage });
|
|
2598
|
-
}, [model, storage, storageScope, userSelectedModel]);
|
|
2599
|
-
useEffect5(() => {
|
|
2600
|
-
const settings = readPiComposerSettings({ storageScope, storage });
|
|
2601
|
-
loadedSettingsSourceRef.current = { storage, storageScope };
|
|
2602
|
-
userSelectedModelRef.current = settings.userSelectedModel;
|
|
2603
|
-
setUserSelectedModel(settings.userSelectedModel);
|
|
2604
|
-
setModelState(settings.model ?? defaultModel ?? null);
|
|
2605
|
-
}, [storage, storageScope]);
|
|
2606
|
-
useEffect5(() => {
|
|
2607
|
-
if (userSelectedModelRef.current || !defaultModel) return;
|
|
2608
|
-
setModelState(defaultModel);
|
|
2609
|
-
}, [defaultModel]);
|
|
2610
2618
|
useEffect5(() => {
|
|
2611
2619
|
if (!enabled) {
|
|
2612
2620
|
setLoaded(true);
|
|
@@ -2618,46 +2626,44 @@ function useChatModelSelection({
|
|
|
2618
2626
|
const nextFetch = fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
2619
2627
|
nextFetch(agentResourceUrl(apiBaseUrl, `/api/v1/agents/${encodeURIComponent(agentTypeId)}/models`), {
|
|
2620
2628
|
headers: withStorageScope(requestHeaders, storageScope)
|
|
2621
|
-
}).then((
|
|
2629
|
+
}).then((response) => response.ok ? response.json() : null).then((payload) => {
|
|
2622
2630
|
if (aborted) return;
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
setUserSelectedModel(false);
|
|
2631
|
+
const models = payload?.models;
|
|
2632
|
+
if (!models) {
|
|
2626
2633
|
setAvailableModels([]);
|
|
2627
|
-
|
|
2628
|
-
writePiComposerModelSelection(null, { storageScope, storage });
|
|
2634
|
+
setSelection((current) => ({ ...current, pendingOverride: void 0, localDefault: sessionModel ?? null }));
|
|
2635
|
+
if (!sessionModel) writePiComposerModelSelection(null, { storageScope, storage });
|
|
2629
2636
|
setLoadedDiscoveryKey(discoveryKey);
|
|
2630
2637
|
setLoaded(true);
|
|
2631
2638
|
return;
|
|
2632
2639
|
}
|
|
2633
|
-
setAvailableModels(
|
|
2640
|
+
setAvailableModels(models);
|
|
2641
|
+
setSelection((current) => {
|
|
2642
|
+
const selected = current.pendingOverride ?? sessionModel ?? current.localDefault;
|
|
2643
|
+
if (availableModel(models, selected)) return current;
|
|
2644
|
+
if (sessionModel) return { ...current, pendingOverride: void 0 };
|
|
2645
|
+
if (sessionId && !sessionIsNew) return { ...current, pendingOverride: void 0, localDefault: null };
|
|
2646
|
+
const firstAvailable = models.find((candidate) => candidate.available);
|
|
2647
|
+
return {
|
|
2648
|
+
...current,
|
|
2649
|
+
pendingOverride: void 0,
|
|
2650
|
+
localDefault: payload.defaultModel ?? (firstAvailable ? { provider: firstAvailable.provider, id: firstAvailable.id } : null)
|
|
2651
|
+
};
|
|
2652
|
+
});
|
|
2634
2653
|
setLoadedDiscoveryKey(discoveryKey);
|
|
2635
2654
|
setLoaded(true);
|
|
2636
|
-
const available = payload.models.filter((m) => m.available);
|
|
2637
|
-
setModelState((current) => {
|
|
2638
|
-
const currentAvailable = current ? available.some((m) => m.provider === current.provider && m.id === current.id) : false;
|
|
2639
|
-
if (currentAvailable) return current;
|
|
2640
|
-
userSelectedModelRef.current = false;
|
|
2641
|
-
setUserSelectedModel(false);
|
|
2642
|
-
writePiComposerModelSelection(null, { storageScope, storage });
|
|
2643
|
-
if (payload.defaultModel) return { provider: payload.defaultModel.provider, id: payload.defaultModel.id };
|
|
2644
|
-
const firstAvailable = available[0];
|
|
2645
|
-
return firstAvailable ? { provider: firstAvailable.provider, id: firstAvailable.id } : null;
|
|
2646
|
-
});
|
|
2647
2655
|
}).catch(() => {
|
|
2648
2656
|
if (aborted) return;
|
|
2649
|
-
userSelectedModelRef.current = false;
|
|
2650
|
-
setUserSelectedModel(false);
|
|
2651
2657
|
setAvailableModels([]);
|
|
2652
|
-
|
|
2653
|
-
writePiComposerModelSelection(null, { storageScope, storage });
|
|
2658
|
+
setSelection((current) => ({ ...current, pendingOverride: void 0, localDefault: sessionModel ?? null }));
|
|
2659
|
+
if (!sessionModel) writePiComposerModelSelection(null, { storageScope, storage });
|
|
2654
2660
|
setLoadedDiscoveryKey(discoveryKey);
|
|
2655
2661
|
setLoaded(true);
|
|
2656
2662
|
});
|
|
2657
2663
|
return () => {
|
|
2658
2664
|
aborted = true;
|
|
2659
2665
|
};
|
|
2660
|
-
}, [agentTypeId, apiBaseUrl, discoveryKey, enabled, fetchImpl, requestHeaders, storage, storageScope]);
|
|
2666
|
+
}, [agentTypeId, apiBaseUrl, discoveryKey, enabled, fetchImpl, requestHeaders, sessionId, sessionIsNew, sessionModel, storage, storageScope]);
|
|
2661
2667
|
useEffect5(() => {
|
|
2662
2668
|
const onChange = (event) => {
|
|
2663
2669
|
const next = parseModelSelection(event.detail);
|
|
@@ -2667,13 +2673,23 @@ function useChatModelSelection({
|
|
|
2667
2673
|
return () => globalThis.removeEventListener?.("boring:model-change", onChange);
|
|
2668
2674
|
}, [setModel]);
|
|
2669
2675
|
const currentDiscoveryLoaded = !enabled || loaded && loadedDiscoveryKey === discoveryKey;
|
|
2670
|
-
const
|
|
2671
|
-
const
|
|
2672
|
-
|
|
2676
|
+
const selectionBelongsToSession = selection.sessionId === sessionId && selection.storage === storage && selection.storageScope === storageScope;
|
|
2677
|
+
const pendingOverride = selectionBelongsToSession ? selection.pendingOverride : void 0;
|
|
2678
|
+
const isOverride = Boolean(pendingOverride && sessionModel && !sameModel(pendingOverride, sessionModel));
|
|
2679
|
+
const sessionAuthorityReady = !sessionId || sessionHydrated && (sessionModel !== void 0 || sessionIsNew);
|
|
2680
|
+
const model = currentDiscoveryLoaded && sessionAuthorityReady ? pendingOverride ?? sessionModel ?? selection.localDefault : null;
|
|
2681
|
+
return {
|
|
2682
|
+
availableModels: currentDiscoveryLoaded ? availableModels : [],
|
|
2683
|
+
loaded: currentDiscoveryLoaded,
|
|
2684
|
+
model,
|
|
2685
|
+
sessionModel,
|
|
2686
|
+
isOverride,
|
|
2687
|
+
setModel
|
|
2688
|
+
};
|
|
2673
2689
|
}
|
|
2674
2690
|
|
|
2675
2691
|
// src/front/hooks/useServerCommands.ts
|
|
2676
|
-
import { useEffect as useEffect6, useRef as
|
|
2692
|
+
import { useEffect as useEffect6, useRef as useRef6, useState as useState8 } from "react";
|
|
2677
2693
|
function serverCommandErrorMessage(body, fallback) {
|
|
2678
2694
|
if (typeof body.error === "string") return body.error;
|
|
2679
2695
|
if (body.error && typeof body.error === "object" && typeof body.error.message === "string") return body.error.message;
|
|
@@ -2725,10 +2741,10 @@ function useServerCommands({
|
|
|
2725
2741
|
refreshKey = 0
|
|
2726
2742
|
}) {
|
|
2727
2743
|
const [stamp, setStamp] = useState8(0);
|
|
2728
|
-
const registrationsRef =
|
|
2744
|
+
const registrationsRef = useRef6({ registry, identity: void 0, names: /* @__PURE__ */ new Set() });
|
|
2729
2745
|
const canonicalSessionId = sessionId.trim() || void 0;
|
|
2730
2746
|
const identityKey = canonicalSessionId ? `${agentTypeId}\0${canonicalSessionId}` : void 0;
|
|
2731
|
-
const identityKeyRef =
|
|
2747
|
+
const identityKeyRef = useRef6(identityKey);
|
|
2732
2748
|
identityKeyRef.current = identityKey;
|
|
2733
2749
|
useEffect6(() => () => {
|
|
2734
2750
|
const registrations = registrationsRef.current;
|
|
@@ -3760,6 +3776,8 @@ function piChatReducer(state, action) {
|
|
|
3760
3776
|
return hydrateFromSnapshot(state, action.snapshot, { allowSeqRewind: action.allowSeqRewind });
|
|
3761
3777
|
case "cursor-sync":
|
|
3762
3778
|
return syncCursor(state, action.cursor);
|
|
3779
|
+
case "model-confirmed":
|
|
3780
|
+
return { ...state, currentModel: action.model };
|
|
3763
3781
|
case "event":
|
|
3764
3782
|
return applySequencedEvent(state, action.event);
|
|
3765
3783
|
case "optimistic-user-message":
|
|
@@ -3856,6 +3874,7 @@ function hydrateFromSnapshot(state, snapshot, options = {}) {
|
|
|
3856
3874
|
...state,
|
|
3857
3875
|
sessionId: snapshot.sessionId,
|
|
3858
3876
|
status: snapshot.status,
|
|
3877
|
+
currentModel: snapshot.currentModel,
|
|
3859
3878
|
turnId: snapshot.activeTurnId,
|
|
3860
3879
|
lastSeq: snapshot.seq,
|
|
3861
3880
|
committedMessages,
|
|
@@ -3906,6 +3925,8 @@ function applySequencedEvent(state, event) {
|
|
|
3906
3925
|
}
|
|
3907
3926
|
function reduceEvent(state, event) {
|
|
3908
3927
|
switch (event.type) {
|
|
3928
|
+
case "model-changed":
|
|
3929
|
+
return { ...state, currentModel: event.currentModel };
|
|
3909
3930
|
case "agent-start":
|
|
3910
3931
|
return { ...state, status: "streaming", turnId: event.turnId, error: void 0, streamingPreservedTextPartKeys: void 0 };
|
|
3911
3932
|
case "agent-end":
|
|
@@ -4638,6 +4659,9 @@ var RemotePiSession = class {
|
|
|
4638
4659
|
else if (!this.suspended) this.ensureReconnectScheduled();
|
|
4639
4660
|
try {
|
|
4640
4661
|
const receipt = await this.postCommand("/prompt", payload, PromptReceiptSchema);
|
|
4662
|
+
if (!this.disposed && payload.model) {
|
|
4663
|
+
this.store.dispatch({ type: "model-confirmed", model: payload.model }, { flush: true });
|
|
4664
|
+
}
|
|
4641
4665
|
return receipt;
|
|
4642
4666
|
} catch (error) {
|
|
4643
4667
|
this.rollbackOptimisticMessage(payload.clientNonce);
|
|
@@ -5212,7 +5236,7 @@ function resolveBootStorage(storage) {
|
|
|
5212
5236
|
}
|
|
5213
5237
|
|
|
5214
5238
|
// src/front/chat/session/usePiSessions.ts
|
|
5215
|
-
import { useCallback as useCallback7, useEffect as useEffect8, useLayoutEffect, useMemo as useMemo4, useRef as
|
|
5239
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useLayoutEffect, useMemo as useMemo4, useRef as useRef7, useState as useState10 } from "react";
|
|
5216
5240
|
var SESSION_PAGE_SIZE = 50;
|
|
5217
5241
|
var DEFAULT_MAX_RETRIES = 60;
|
|
5218
5242
|
var DEFAULT_RETRY_BASE_MS = 250;
|
|
@@ -5275,22 +5299,22 @@ function usePiSessions(options) {
|
|
|
5275
5299
|
const [loadingMore, setLoadingMore] = useState10(false);
|
|
5276
5300
|
const [hasMore, setHasMore] = useState10(false);
|
|
5277
5301
|
const [error, setError] = useState10(void 0);
|
|
5278
|
-
const mountedRef =
|
|
5279
|
-
const refreshVersionRef =
|
|
5280
|
-
const retryTimerRef =
|
|
5281
|
-
const sessionsRef =
|
|
5282
|
-
const activeSessionIdRef =
|
|
5283
|
-
const hasMoreRef =
|
|
5284
|
-
const canonicalLoadedCountRef =
|
|
5285
|
-
const nextCursorRef =
|
|
5286
|
-
const loadMoreRequestSeqRef =
|
|
5287
|
-
const loadMoreInFlightRef =
|
|
5288
|
-
const pendingCreatedRef =
|
|
5289
|
-
const pendingDeletedRef =
|
|
5290
|
-
const pendingCreatedScopeRef =
|
|
5291
|
-
const dataStorageScopeRef =
|
|
5292
|
-
const loadedDataSourceRef =
|
|
5293
|
-
const committedRequestScopeRef =
|
|
5302
|
+
const mountedRef = useRef7(false);
|
|
5303
|
+
const refreshVersionRef = useRef7(0);
|
|
5304
|
+
const retryTimerRef = useRef7(void 0);
|
|
5305
|
+
const sessionsRef = useRef7([]);
|
|
5306
|
+
const activeSessionIdRef = useRef7(activeSessionId);
|
|
5307
|
+
const hasMoreRef = useRef7(hasMore);
|
|
5308
|
+
const canonicalLoadedCountRef = useRef7(0);
|
|
5309
|
+
const nextCursorRef = useRef7(void 0);
|
|
5310
|
+
const loadMoreRequestSeqRef = useRef7(0);
|
|
5311
|
+
const loadMoreInFlightRef = useRef7(false);
|
|
5312
|
+
const pendingCreatedRef = useRef7(/* @__PURE__ */ new Map());
|
|
5313
|
+
const pendingDeletedRef = useRef7(/* @__PURE__ */ new Set());
|
|
5314
|
+
const pendingCreatedScopeRef = useRef7(requestScopeKey);
|
|
5315
|
+
const dataStorageScopeRef = useRef7(storageScope);
|
|
5316
|
+
const loadedDataSourceRef = useRef7(dataSourceKey);
|
|
5317
|
+
const committedRequestScopeRef = useRef7(requestScopeKey);
|
|
5294
5318
|
useIsomorphicLayoutEffect(() => {
|
|
5295
5319
|
committedRequestScopeRef.current = requestScopeKey;
|
|
5296
5320
|
}, [requestScopeKey]);
|
|
@@ -5298,7 +5322,7 @@ function usePiSessions(options) {
|
|
|
5298
5322
|
(scope) => mountedRef.current && committedRequestScopeRef.current === scope,
|
|
5299
5323
|
[]
|
|
5300
5324
|
);
|
|
5301
|
-
const remoteSessionOptionsRef =
|
|
5325
|
+
const remoteSessionOptionsRef = useRef7(options.remoteSessionOptions);
|
|
5302
5326
|
remoteSessionOptionsRef.current = options.remoteSessionOptions;
|
|
5303
5327
|
const remoteSessionOptionsKey = useMemo4(
|
|
5304
5328
|
() => remoteSessionOptionsIdentity(options.remoteSessionOptions),
|
|
@@ -6149,7 +6173,7 @@ function searchPiSessions(sessions, query, options = {}) {
|
|
|
6149
6173
|
|
|
6150
6174
|
// src/front/chat/components/PiConversationSurface.tsx
|
|
6151
6175
|
import { Skeleton } from "@hachej/boring-ui-kit";
|
|
6152
|
-
import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect as useLayoutEffect2, useRef as
|
|
6176
|
+
import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect as useLayoutEffect2, useRef as useRef10, useState as useState15 } from "react";
|
|
6153
6177
|
import { useStickToBottomContext as useStickToBottomContext2 } from "use-stick-to-bottom";
|
|
6154
6178
|
|
|
6155
6179
|
// src/front/primitives/conversation.tsx
|
|
@@ -6497,7 +6521,7 @@ function QueuedComposerNotice({ followUps, onEdit }) {
|
|
|
6497
6521
|
}
|
|
6498
6522
|
|
|
6499
6523
|
// src/front/chat/components/PiTimelineMessage.tsx
|
|
6500
|
-
import { useCallback as useCallback13, useEffect as useEffect13, useMemo as useMemo12, useRef as
|
|
6524
|
+
import { useCallback as useCallback13, useEffect as useEffect13, useMemo as useMemo12, useRef as useRef9, useState as useState14 } from "react";
|
|
6501
6525
|
import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon3 } from "lucide-react";
|
|
6502
6526
|
import { Button as Button10 } from "@hachej/boring-ui-kit";
|
|
6503
6527
|
|
|
@@ -6921,7 +6945,7 @@ import {
|
|
|
6921
6945
|
useContext as useContext5,
|
|
6922
6946
|
useEffect as useEffect11,
|
|
6923
6947
|
useMemo as useMemo9,
|
|
6924
|
-
useRef as
|
|
6948
|
+
useRef as useRef8,
|
|
6925
6949
|
useState as useState12
|
|
6926
6950
|
} from "react";
|
|
6927
6951
|
import { Streamdown as Streamdown2 } from "streamdown";
|
|
@@ -7013,9 +7037,9 @@ var Reasoning = memo5(
|
|
|
7013
7037
|
defaultProp: void 0,
|
|
7014
7038
|
prop: durationProp
|
|
7015
7039
|
});
|
|
7016
|
-
const hasEverStreamedRef =
|
|
7040
|
+
const hasEverStreamedRef = useRef8(isStreaming);
|
|
7017
7041
|
const [hasAutoClosed, setHasAutoClosed] = useState12(false);
|
|
7018
|
-
const startTimeRef =
|
|
7042
|
+
const startTimeRef = useRef8(null);
|
|
7019
7043
|
useEffect11(() => {
|
|
7020
7044
|
if (isStreaming) {
|
|
7021
7045
|
hasEverStreamedRef.current = true;
|
|
@@ -7606,7 +7630,7 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
|
|
|
7606
7630
|
...effectiveMentionCatalog.skills.map((skill) => `skill:${skill.name}:${skill.commandName}`),
|
|
7607
7631
|
effectiveMentionCatalog.files ? "files:enabled" : "files:disabled"
|
|
7608
7632
|
].join("|");
|
|
7609
|
-
const mentionActivateRef =
|
|
7633
|
+
const mentionActivateRef = useRef9(onMentionActivate);
|
|
7610
7634
|
mentionActivateRef.current = onMentionActivate;
|
|
7611
7635
|
const activateCurrentMention = useCallback13((mention) => {
|
|
7612
7636
|
if (mention.kind === "file") {
|
|
@@ -8078,8 +8102,8 @@ function ConversationHistoryLoadingState() {
|
|
|
8078
8102
|
}
|
|
8079
8103
|
function TranscriptHistoryLoader({ olderCount, onLoadOlder }) {
|
|
8080
8104
|
const { scrollRef } = useStickToBottomContext2();
|
|
8081
|
-
const pendingAnchor =
|
|
8082
|
-
const armed =
|
|
8105
|
+
const pendingAnchor = useRef10(null);
|
|
8106
|
+
const armed = useRef10(true);
|
|
8083
8107
|
useEffect14(() => {
|
|
8084
8108
|
const el = scrollRef.current;
|
|
8085
8109
|
if (!el) return;
|
|
@@ -8144,7 +8168,7 @@ import { useCallback as useCallback16, useLayoutEffect as useLayoutEffect3 } fro
|
|
|
8144
8168
|
import { motion as motion2, useReducedMotion } from "motion/react";
|
|
8145
8169
|
|
|
8146
8170
|
// src/front/composer/PluginUpdateStatus.tsx
|
|
8147
|
-
import { useEffect as useEffect15, useRef as
|
|
8171
|
+
import { useEffect as useEffect15, useRef as useRef11 } from "react";
|
|
8148
8172
|
|
|
8149
8173
|
// src/front/composer/ComposerStatusBanner.tsx
|
|
8150
8174
|
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
@@ -8267,7 +8291,7 @@ function PluginUpdateStatus({
|
|
|
8267
8291
|
successAutoDismissMs = 1400,
|
|
8268
8292
|
maxWidthClassName = "max-w-3xl"
|
|
8269
8293
|
}) {
|
|
8270
|
-
const onDismissRef =
|
|
8294
|
+
const onDismissRef = useRef11(onDismiss);
|
|
8271
8295
|
useEffect15(() => {
|
|
8272
8296
|
onDismissRef.current = onDismiss;
|
|
8273
8297
|
}, [onDismiss]);
|
|
@@ -8383,7 +8407,7 @@ function PluginUpdateStatus({
|
|
|
8383
8407
|
}
|
|
8384
8408
|
|
|
8385
8409
|
// src/front/composer/CommandRunStatus.tsx
|
|
8386
|
-
import { useEffect as useEffect16, useRef as
|
|
8410
|
+
import { useEffect as useEffect16, useRef as useRef12 } from "react";
|
|
8387
8411
|
import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
8388
8412
|
function CommandRunStatus({
|
|
8389
8413
|
state,
|
|
@@ -8391,7 +8415,7 @@ function CommandRunStatus({
|
|
|
8391
8415
|
successAutoDismissMs = 1400,
|
|
8392
8416
|
maxWidthClassName = "max-w-3xl"
|
|
8393
8417
|
}) {
|
|
8394
|
-
const onDismissRef =
|
|
8418
|
+
const onDismissRef = useRef12(onDismiss);
|
|
8395
8419
|
useEffect16(() => {
|
|
8396
8420
|
onDismissRef.current = onDismiss;
|
|
8397
8421
|
}, [onDismiss]);
|
|
@@ -8463,7 +8487,7 @@ function CommandRunStatus({
|
|
|
8463
8487
|
}
|
|
8464
8488
|
|
|
8465
8489
|
// src/front/chatPanelComposerControls.tsx
|
|
8466
|
-
import { forwardRef, useEffect as useEffect17, useRef as
|
|
8490
|
+
import { forwardRef, useEffect as useEffect17, useRef as useRef13, useState as useState16 } from "react";
|
|
8467
8491
|
import { CheckIcon as CheckIcon3, ChevronDownIcon as ChevronDownIcon5 } from "lucide-react";
|
|
8468
8492
|
import {
|
|
8469
8493
|
Command,
|
|
@@ -8611,6 +8635,8 @@ function groupModelOptions(options) {
|
|
|
8611
8635
|
var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
|
|
8612
8636
|
value,
|
|
8613
8637
|
options,
|
|
8638
|
+
sessionModel,
|
|
8639
|
+
isOverride = false,
|
|
8614
8640
|
disabled,
|
|
8615
8641
|
trigger = "button",
|
|
8616
8642
|
open = false,
|
|
@@ -8620,7 +8646,10 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
|
|
|
8620
8646
|
...props
|
|
8621
8647
|
}, ref) {
|
|
8622
8648
|
const triggerLabel = modelTriggerLabel(value, options, emptyLabel);
|
|
8649
|
+
const sessionTriggerLabel = sessionModel ? modelTriggerLabel(sessionModel, options) : void 0;
|
|
8623
8650
|
const triggerDisplay = value ? `${triggerLabel} (${displayProviderLabel(value.provider)})` : triggerLabel;
|
|
8651
|
+
const sessionDisplay = sessionModel && sessionTriggerLabel ? `${sessionTriggerLabel} (${displayProviderLabel(sessionModel.provider)})` : triggerDisplay;
|
|
8652
|
+
const accessibleDisplay = isOverride && value ? `Current model: ${sessionDisplay}. Next-message override: ${triggerDisplay}` : `Current model: ${sessionDisplay}`;
|
|
8624
8653
|
return /* @__PURE__ */ jsx28(
|
|
8625
8654
|
"button",
|
|
8626
8655
|
{
|
|
@@ -8628,9 +8657,10 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
|
|
|
8628
8657
|
type: "button",
|
|
8629
8658
|
"data-boring-agent-part": "model-select",
|
|
8630
8659
|
"data-boring-state": disabled ? "disabled" : void 0,
|
|
8660
|
+
"data-boring-model-override": isOverride ? "true" : void 0,
|
|
8631
8661
|
disabled,
|
|
8632
|
-
"aria-label": trigger === "slash" ? `Open model picker.
|
|
8633
|
-
title: trigger === "slash" ?
|
|
8662
|
+
"aria-label": trigger === "slash" ? `Open model picker. ${accessibleDisplay}` : "Model",
|
|
8663
|
+
title: trigger === "slash" ? accessibleDisplay : void 0,
|
|
8634
8664
|
onClick,
|
|
8635
8665
|
className: cn(
|
|
8636
8666
|
trigger === "slash" ? "h-8 max-w-[min(68vw,420px)] cursor-pointer overflow-hidden text-ellipsis whitespace-nowrap rounded-[var(--radius-md)] px-2 text-xs transition-colors hover:bg-muted/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-popover disabled:pointer-events-none disabled:opacity-50 motion-reduce:transition-none" : selectorTriggerClass,
|
|
@@ -8641,8 +8671,17 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
|
|
|
8641
8671
|
...props,
|
|
8642
8672
|
children: trigger === "slash" ? /* @__PURE__ */ jsxs24(Fragment11, { children: [
|
|
8643
8673
|
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Model \xB7 " }),
|
|
8644
|
-
/* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate text-foreground", children: triggerLabel }),
|
|
8645
|
-
|
|
8674
|
+
/* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate text-foreground", children: sessionTriggerLabel ?? triggerLabel }),
|
|
8675
|
+
sessionModel ? /* @__PURE__ */ jsxs24("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
8676
|
+
" \xB7 ",
|
|
8677
|
+
displayProviderLabel(sessionModel.provider)
|
|
8678
|
+
] }) : value ? /* @__PURE__ */ jsxs24("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
8679
|
+
" \xB7 ",
|
|
8680
|
+
displayProviderLabel(value.provider)
|
|
8681
|
+
] }) : null,
|
|
8682
|
+
isOverride && value ? /* @__PURE__ */ jsxs24("span", { className: "shrink-0 text-amber-600 dark:text-amber-400", children: [
|
|
8683
|
+
" \xB7 Next override: ",
|
|
8684
|
+
triggerLabel,
|
|
8646
8685
|
" \xB7 ",
|
|
8647
8686
|
displayProviderLabel(value.provider)
|
|
8648
8687
|
] }) : null
|
|
@@ -8669,8 +8708,8 @@ function ModelPickerMenu({
|
|
|
8669
8708
|
const keyboardOptions = hideDefaultOption ? groupedOptions : [null, ...groupedOptions];
|
|
8670
8709
|
const selectedIndex = currentKey ? Math.max(0, keyboardOptions.findIndex((option) => option && encodeModelKey(option) === currentKey)) : 0;
|
|
8671
8710
|
const [activeIndex, setActiveIndex] = useState16(selectedIndex);
|
|
8672
|
-
const activeIndexRef =
|
|
8673
|
-
const menuRef =
|
|
8711
|
+
const activeIndexRef = useRef13(selectedIndex);
|
|
8712
|
+
const menuRef = useRef13(null);
|
|
8674
8713
|
useDismissOnOutsidePointer(menuRef, onClose);
|
|
8675
8714
|
const setKeyboardActiveIndex = (next) => {
|
|
8676
8715
|
const resolved = typeof next === "function" ? next(activeIndexRef.current) : next;
|
|
@@ -8797,7 +8836,7 @@ function ModelSelect({
|
|
|
8797
8836
|
hideDefaultOption = false
|
|
8798
8837
|
}) {
|
|
8799
8838
|
const [open, setOpen] = useState16(false);
|
|
8800
|
-
const previousOpenSignalRef =
|
|
8839
|
+
const previousOpenSignalRef = useRef13(openSignal);
|
|
8801
8840
|
useEffect17(() => {
|
|
8802
8841
|
if (disabled) setOpen(false);
|
|
8803
8842
|
}, [disabled]);
|
|
@@ -8858,7 +8897,7 @@ function ThinkingSelect({
|
|
|
8858
8897
|
className
|
|
8859
8898
|
}) {
|
|
8860
8899
|
const [open, setOpen] = useState16(false);
|
|
8861
|
-
const previousOpenSignalRef =
|
|
8900
|
+
const previousOpenSignalRef = useRef13(openSignal);
|
|
8862
8901
|
useEffect17(() => {
|
|
8863
8902
|
if (disabled) setOpen(false);
|
|
8864
8903
|
}, [disabled]);
|
|
@@ -8955,8 +8994,8 @@ function ThinkingPickerMenu({
|
|
|
8955
8994
|
}) {
|
|
8956
8995
|
const selectedIndex = Math.max(0, THINKING_LEVELS.indexOf(value));
|
|
8957
8996
|
const [activeIndex, setActiveIndex] = useState16(selectedIndex);
|
|
8958
|
-
const activeIndexRef =
|
|
8959
|
-
const menuRef =
|
|
8997
|
+
const activeIndexRef = useRef13(selectedIndex);
|
|
8998
|
+
const menuRef = useRef13(null);
|
|
8960
8999
|
useDismissOnOutsidePointer(menuRef, onClose);
|
|
8961
9000
|
const setKeyboardActiveIndex = (next) => {
|
|
8962
9001
|
const resolved = typeof next === "function" ? next(activeIndexRef.current) : next;
|
|
@@ -9052,7 +9091,7 @@ import {
|
|
|
9052
9091
|
XIcon as XIcon4
|
|
9053
9092
|
} from "lucide-react";
|
|
9054
9093
|
import { nanoid } from "nanoid";
|
|
9055
|
-
import { useCallback as useCallback15, useEffect as useEffect18, useMemo as useMemo13, useRef as
|
|
9094
|
+
import { useCallback as useCallback15, useEffect as useEffect18, useMemo as useMemo13, useRef as useRef14, useState as useState17 } from "react";
|
|
9056
9095
|
|
|
9057
9096
|
// src/front/primitives/prompt-input-context.ts
|
|
9058
9097
|
import { createContext as createContext7, useContext as useContext7 } from "react";
|
|
@@ -9119,12 +9158,12 @@ var PromptInput = ({
|
|
|
9119
9158
|
}) => {
|
|
9120
9159
|
const controller = useOptionalPromptInputController();
|
|
9121
9160
|
const usingProvider = !!controller;
|
|
9122
|
-
const providerTextValueRef =
|
|
9161
|
+
const providerTextValueRef = useRef14("");
|
|
9123
9162
|
if (usingProvider) {
|
|
9124
9163
|
providerTextValueRef.current = controller.textInput.value;
|
|
9125
9164
|
}
|
|
9126
|
-
const inputRef =
|
|
9127
|
-
const formRef =
|
|
9165
|
+
const inputRef = useRef14(null);
|
|
9166
|
+
const formRef = useRef14(null);
|
|
9128
9167
|
const [items, setItems] = useState17([]);
|
|
9129
9168
|
const setFileUrlLocal = useCallback15((id, url, status, path) => {
|
|
9130
9169
|
setItems((prev) => prev.map((f) => {
|
|
@@ -9135,7 +9174,7 @@ var PromptInput = ({
|
|
|
9135
9174
|
}, []);
|
|
9136
9175
|
const files = usingProvider ? controller.attachments.files : items;
|
|
9137
9176
|
const [referencedSources, setReferencedSources] = useState17([]);
|
|
9138
|
-
const filesRef =
|
|
9177
|
+
const filesRef = useRef14(files);
|
|
9139
9178
|
useEffect18(() => {
|
|
9140
9179
|
filesRef.current = files;
|
|
9141
9180
|
}, [files]);
|
|
@@ -9613,7 +9652,7 @@ var PromptInputSubmit = ({
|
|
|
9613
9652
|
};
|
|
9614
9653
|
|
|
9615
9654
|
// src/front/primitives/slash-command-picker.tsx
|
|
9616
|
-
import { useEffect as useEffect19, useMemo as useMemo14, useRef as
|
|
9655
|
+
import { useEffect as useEffect19, useMemo as useMemo14, useRef as useRef15, useState as useState18 } from "react";
|
|
9617
9656
|
import { Fragment as Fragment13, jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
9618
9657
|
var ALL_PLUGINS = "__all__";
|
|
9619
9658
|
function commandGroup(cmd) {
|
|
@@ -9625,9 +9664,9 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9625
9664
|
const [plugin, setPlugin] = useState18(ALL_PLUGINS);
|
|
9626
9665
|
const [searchQuery, setSearchQuery] = useState18(query);
|
|
9627
9666
|
const [activeIdx, setActiveIdx] = useState18(0);
|
|
9628
|
-
const containerRef =
|
|
9629
|
-
const listRef =
|
|
9630
|
-
const inputRef =
|
|
9667
|
+
const containerRef = useRef15(null);
|
|
9668
|
+
const listRef = useRef15(null);
|
|
9669
|
+
const inputRef = useRef15(null);
|
|
9631
9670
|
useEffect19(() => {
|
|
9632
9671
|
setSearchQuery(query);
|
|
9633
9672
|
}, [query]);
|
|
@@ -9862,6 +9901,8 @@ function PiChatComposerSurface({
|
|
|
9862
9901
|
onDismissSlash,
|
|
9863
9902
|
modelPickerOpen,
|
|
9864
9903
|
selectedModel,
|
|
9904
|
+
sessionModel,
|
|
9905
|
+
modelOverride,
|
|
9865
9906
|
modelOptions,
|
|
9866
9907
|
modelControlled,
|
|
9867
9908
|
hideDefaultModelOption = false,
|
|
@@ -10172,6 +10213,8 @@ function PiChatComposerSurface({
|
|
|
10172
10213
|
ModelSelectTrigger,
|
|
10173
10214
|
{
|
|
10174
10215
|
value: selectedModel,
|
|
10216
|
+
sessionModel,
|
|
10217
|
+
isOverride: modelOverride,
|
|
10175
10218
|
options: modelOptions,
|
|
10176
10219
|
disabled: isStreaming || modelControlled,
|
|
10177
10220
|
trigger: "slash",
|
|
@@ -10215,7 +10258,7 @@ function getHeaderValue(headers, name) {
|
|
|
10215
10258
|
}
|
|
10216
10259
|
|
|
10217
10260
|
// src/front/chat/piChatPanelHooks.ts
|
|
10218
|
-
import { useCallback as useCallback17, useEffect as useEffect20, useMemo as useMemo15, useRef as
|
|
10261
|
+
import { useCallback as useCallback17, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef16, useState as useState19, useSyncExternalStore } from "react";
|
|
10219
10262
|
|
|
10220
10263
|
// src/front/chat/piChatPanelUtils.ts
|
|
10221
10264
|
function headersContentKey(headers) {
|
|
@@ -10336,7 +10379,7 @@ function useExternalRemotePiSession({
|
|
|
10336
10379
|
enabled = true
|
|
10337
10380
|
}) {
|
|
10338
10381
|
const [session, setSession] = useState19();
|
|
10339
|
-
const remoteSessionOptionsRef =
|
|
10382
|
+
const remoteSessionOptionsRef = useRef16(remoteSessionOptions);
|
|
10340
10383
|
remoteSessionOptionsRef.current = remoteSessionOptions;
|
|
10341
10384
|
const requestHeadersKey = headersContentKey(requestHeaders);
|
|
10342
10385
|
const stableRequestHeaders = useMemo15(
|
|
@@ -10489,11 +10532,11 @@ function PiChatPanel({
|
|
|
10489
10532
|
}) {
|
|
10490
10533
|
const externalSessionId = sessionId?.trim() || void 0;
|
|
10491
10534
|
const showSessionSidebar = showSessions ?? externalSessionId === void 0;
|
|
10492
|
-
const onDataRef =
|
|
10535
|
+
const onDataRef = useRef17(onData);
|
|
10493
10536
|
onDataRef.current = onData;
|
|
10494
|
-
const onTurnCompleteRef =
|
|
10537
|
+
const onTurnCompleteRef = useRef17(onTurnComplete);
|
|
10495
10538
|
onTurnCompleteRef.current = onTurnComplete;
|
|
10496
|
-
const sessionListRefreshRef =
|
|
10539
|
+
const sessionListRefreshRef = useRef17(void 0);
|
|
10497
10540
|
const requestHeadersKey = useMemo16(() => headersContentKey(requestHeaders), [requestHeaders]);
|
|
10498
10541
|
const normalizedRequestHeaders = useMemo16(() => normalizedHeadersFromContentKey(requestHeadersKey), [requestHeadersKey]);
|
|
10499
10542
|
const remoteSessionOptionsWithEvents = useMemo16(() => ({
|
|
@@ -10557,13 +10600,21 @@ function PiChatPanel({
|
|
|
10557
10600
|
agentTypeId,
|
|
10558
10601
|
apiBaseUrl,
|
|
10559
10602
|
defaultModel,
|
|
10603
|
+
sessionId: activeSessionId,
|
|
10604
|
+
sessionHydrated: selectedChatState?.hydrated ?? false,
|
|
10605
|
+
sessionIsNew: Boolean(
|
|
10606
|
+
selectedChatState?.hydrated && selectedChatState.history.messageCount === 0 && selectedChatState.committedMessages.length === 0 && selectedChatState.queue.followUps.length === 0 && Object.keys(selectedChatState.optimisticOutbox).length === 0 && !selectedChatState.streamingMessage
|
|
10607
|
+
),
|
|
10608
|
+
sessionModel: selectedChatState?.currentModel,
|
|
10560
10609
|
fetch: fetch2,
|
|
10561
10610
|
requestHeaders: normalizedRequestHeaders,
|
|
10562
10611
|
storage,
|
|
10563
10612
|
storageScope,
|
|
10564
10613
|
enabled: modelDiscoveryEnabled
|
|
10565
10614
|
});
|
|
10615
|
+
const sessionModel = selectedChatState?.currentModel;
|
|
10566
10616
|
const selectedModel = model === void 0 ? modelDiscovery.model : model;
|
|
10617
|
+
const modelOverride = model === void 0 ? modelDiscovery.isOverride : Boolean(model && sessionModel && (model.provider !== sessionModel.provider || model.id !== sessionModel.id));
|
|
10567
10618
|
const modelOptions = useMemo16(
|
|
10568
10619
|
() => modelOptionsForSelection(availableModels ?? modelDiscovery.availableModels, selectedModel),
|
|
10569
10620
|
[availableModels, modelDiscovery.availableModels, selectedModel]
|
|
@@ -10602,13 +10653,13 @@ function PiChatPanel({
|
|
|
10602
10653
|
const [modelPickerOpen, setModelPickerOpen] = useState20(false);
|
|
10603
10654
|
const [thinkingPickerOpen, setThinkingPickerOpen] = useState20(false);
|
|
10604
10655
|
const [draft, setDraft] = useState20(() => initialDraft ?? "");
|
|
10605
|
-
const draftRef =
|
|
10656
|
+
const draftRef = useRef17(draft);
|
|
10606
10657
|
draftRef.current = draft;
|
|
10607
|
-
const initialDraftGuard =
|
|
10608
|
-
const pendingAutoSubmitSettleRef =
|
|
10609
|
-
const acceptedAutoSubmitSettleRef =
|
|
10610
|
-
const resetInProgressRef =
|
|
10611
|
-
const autoCreateInFlightRef =
|
|
10658
|
+
const initialDraftGuard = useRef17(new InitialDraftAutoSubmitGuard());
|
|
10659
|
+
const pendingAutoSubmitSettleRef = useRef17(void 0);
|
|
10660
|
+
const acceptedAutoSubmitSettleRef = useRef17(void 0);
|
|
10661
|
+
const resetInProgressRef = useRef17(false);
|
|
10662
|
+
const autoCreateInFlightRef = useRef17(false);
|
|
10612
10663
|
const settlePendingAutoSubmit = useCallback18((sessionId2) => {
|
|
10613
10664
|
const pendingSessionId = pendingAutoSubmitSettleRef.current;
|
|
10614
10665
|
if (!pendingSessionId || sessionId2 && pendingSessionId !== sessionId2) return false;
|
|
@@ -10617,19 +10668,19 @@ function PiChatPanel({
|
|
|
10617
10668
|
onAutoSubmitInitialDraftSettled?.();
|
|
10618
10669
|
return true;
|
|
10619
10670
|
}, [onAutoSubmitInitialDraftSettled]);
|
|
10620
|
-
const prevStatusRef =
|
|
10621
|
-
const statusRef =
|
|
10622
|
-
const scrollToBottomRef =
|
|
10671
|
+
const prevStatusRef = useRef17("idle");
|
|
10672
|
+
const statusRef = useRef17("idle");
|
|
10673
|
+
const scrollToBottomRef = useRef17(() => {
|
|
10623
10674
|
});
|
|
10624
|
-
const textareaRef =
|
|
10675
|
+
const textareaRef = useRef17(null);
|
|
10625
10676
|
const [localNotices, setLocalNotices] = useState20([]);
|
|
10626
10677
|
const [dismissedNoticeIds, setDismissedNoticeIds] = useState20(() => /* @__PURE__ */ new Set());
|
|
10627
10678
|
const [pluginUpdateState, setPluginUpdateState] = useState20(null);
|
|
10628
10679
|
const [commandNotifyState, setCommandNotifyState] = useState20(null);
|
|
10629
|
-
const commandRunIdRef =
|
|
10680
|
+
const commandRunIdRef = useRef17(0);
|
|
10630
10681
|
const [serverSkillsRefreshKey, setServerSkillsRefreshKey] = useState20(0);
|
|
10631
10682
|
const [localSubmittedSessionId, setLocalSubmittedSessionId] = useState20();
|
|
10632
|
-
const localSubmittedSessionRef =
|
|
10683
|
+
const localSubmittedSessionRef = useRef17(void 0);
|
|
10633
10684
|
const { attachmentNotice, setAttachmentNotice } = useAttachmentNotice();
|
|
10634
10685
|
const composerContributions = useComposerContributions();
|
|
10635
10686
|
const contributedCommands = useMemo16(
|
|
@@ -11261,6 +11312,8 @@ function PiChatPanel({
|
|
|
11261
11312
|
onDismissSlash: dismissSlash,
|
|
11262
11313
|
modelPickerOpen,
|
|
11263
11314
|
selectedModel,
|
|
11315
|
+
sessionModel,
|
|
11316
|
+
modelOverride,
|
|
11264
11317
|
modelOptions,
|
|
11265
11318
|
modelControlled: model !== void 0,
|
|
11266
11319
|
hideDefaultModelOption,
|