pi-ui-extend 0.1.25 → 0.1.26
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.
|
@@ -363,6 +363,9 @@ export class AppSessionEventController {
|
|
|
363
363
|
}
|
|
364
364
|
if (!this.assistantTextBuffer)
|
|
365
365
|
return visibleText;
|
|
366
|
+
if (!final && shouldHoldAssistantStreamWhitespaceTail(this.assistantTextBuffer, this.hasVisibleAssistantText(visibleText))) {
|
|
367
|
+
return visibleText;
|
|
368
|
+
}
|
|
366
369
|
if (shouldHoldAssistantStreamTail(this.assistantTextBuffer, this.hasVisibleAssistantText(visibleText))) {
|
|
367
370
|
if (final)
|
|
368
371
|
this.assistantTextBuffer = "";
|
|
@@ -445,6 +448,9 @@ function shouldHoldAssistantStreamTail(text, hasVisibleText) {
|
|
|
445
448
|
return !hasVisibleText;
|
|
446
449
|
return isPotentialDcpMetadataLine(text);
|
|
447
450
|
}
|
|
451
|
+
function shouldHoldAssistantStreamWhitespaceTail(text, hasVisibleText) {
|
|
452
|
+
return hasVisibleText && text.trim().length === 0;
|
|
453
|
+
}
|
|
448
454
|
function isHiddenMarkdownMetadataLine(line) {
|
|
449
455
|
return isMarkdownReferenceDefinition(line) || isPotentialDcpMetadataLine(line);
|
|
450
456
|
}
|
|
@@ -41,8 +41,10 @@ export declare class AppTabsController {
|
|
|
41
41
|
private readonly runtimeLoadsByTabId;
|
|
42
42
|
private readonly runtimeSubscriptionsByTabId;
|
|
43
43
|
private readonly runtimeRefreshTimersByTabId;
|
|
44
|
+
private readonly historyReloadTimersByTabId;
|
|
44
45
|
private readonly inputStatesByTabId;
|
|
45
46
|
private readonly deferredUserMessagesByTabId;
|
|
47
|
+
private readonly tabIdsNeedingHistoryReload;
|
|
46
48
|
private activeTabId;
|
|
47
49
|
private pendingActiveTabId;
|
|
48
50
|
private historyLoadGeneration;
|
|
@@ -89,6 +91,9 @@ export declare class AppTabsController {
|
|
|
89
91
|
private shouldScheduleDelayedSyncForRuntimeEvent;
|
|
90
92
|
private scheduleDelayedRuntimeSync;
|
|
91
93
|
private clearRuntimeRefreshTimers;
|
|
94
|
+
private clearHistoryReloadTimers;
|
|
95
|
+
private scheduleDelayedHistoryReload;
|
|
96
|
+
private reloadActiveTabHistoryIfNeeded;
|
|
92
97
|
private syncTabFromObservedRuntime;
|
|
93
98
|
private storeActiveInputState;
|
|
94
99
|
private storeActiveDeferredUserMessages;
|
|
@@ -20,8 +20,10 @@ export class AppTabsController {
|
|
|
20
20
|
runtimeLoadsByTabId = new Map();
|
|
21
21
|
runtimeSubscriptionsByTabId = new Map();
|
|
22
22
|
runtimeRefreshTimersByTabId = new Map();
|
|
23
|
+
historyReloadTimersByTabId = new Map();
|
|
23
24
|
inputStatesByTabId = new Map();
|
|
24
25
|
deferredUserMessagesByTabId = new Map();
|
|
26
|
+
tabIdsNeedingHistoryReload = new Set();
|
|
25
27
|
activeTabId;
|
|
26
28
|
pendingActiveTabId;
|
|
27
29
|
historyLoadGeneration = 0;
|
|
@@ -632,6 +634,7 @@ export class AppTabsController {
|
|
|
632
634
|
void this.saveTabs();
|
|
633
635
|
this.scheduleTabPrewarm();
|
|
634
636
|
await this.loadActiveSessionHistory(targetRuntime);
|
|
637
|
+
this.scheduleDelayedHistoryReload(target.id, targetRuntime);
|
|
635
638
|
}
|
|
636
639
|
async closeTab(tabId) {
|
|
637
640
|
if (this.pendingActiveTabId) {
|
|
@@ -814,6 +817,8 @@ export class AppTabsController {
|
|
|
814
817
|
this.runtimesByTabId.delete(tabId);
|
|
815
818
|
this.runtimeLoadsByTabId.delete(tabId);
|
|
816
819
|
this.clearRuntimeRefreshTimers(tabId);
|
|
820
|
+
this.clearHistoryReloadTimers(tabId);
|
|
821
|
+
this.tabIdsNeedingHistoryReload.delete(tabId);
|
|
817
822
|
const subscription = this.runtimeSubscriptionsByTabId.get(tabId);
|
|
818
823
|
subscription?.unsubscribe();
|
|
819
824
|
this.runtimeSubscriptionsByTabId.delete(tabId);
|
|
@@ -822,6 +827,9 @@ export class AppTabsController {
|
|
|
822
827
|
for (const tabId of this.runtimeRefreshTimersByTabId.keys()) {
|
|
823
828
|
this.clearRuntimeRefreshTimers(tabId);
|
|
824
829
|
}
|
|
830
|
+
for (const tabId of this.historyReloadTimersByTabId.keys()) {
|
|
831
|
+
this.clearHistoryReloadTimers(tabId);
|
|
832
|
+
}
|
|
825
833
|
for (const subscription of this.runtimeSubscriptionsByTabId.values()) {
|
|
826
834
|
subscription.unsubscribe();
|
|
827
835
|
}
|
|
@@ -835,6 +843,7 @@ export class AppTabsController {
|
|
|
835
843
|
const unsubscribe = runtime.session.subscribe((event) => {
|
|
836
844
|
if (this.shouldScheduleDelayedSyncForRuntimeEvent(event)) {
|
|
837
845
|
this.scheduleDelayedRuntimeSync(tabId, runtime);
|
|
846
|
+
this.tabIdsNeedingHistoryReload.add(tabId);
|
|
838
847
|
}
|
|
839
848
|
if (!this.shouldSyncTabFromRuntimeEvent(event))
|
|
840
849
|
return;
|
|
@@ -878,6 +887,44 @@ export class AppTabsController {
|
|
|
878
887
|
clearTimeout(timer);
|
|
879
888
|
this.runtimeRefreshTimersByTabId.delete(tabId);
|
|
880
889
|
}
|
|
890
|
+
clearHistoryReloadTimers(tabId) {
|
|
891
|
+
const timers = this.historyReloadTimersByTabId.get(tabId);
|
|
892
|
+
if (!timers)
|
|
893
|
+
return;
|
|
894
|
+
for (const timer of timers)
|
|
895
|
+
clearTimeout(timer);
|
|
896
|
+
this.historyReloadTimersByTabId.delete(tabId);
|
|
897
|
+
}
|
|
898
|
+
scheduleDelayedHistoryReload(tabId, runtime) {
|
|
899
|
+
if (!this.tabIdsNeedingHistoryReload.has(tabId))
|
|
900
|
+
return;
|
|
901
|
+
if (tabId !== this.activeTabId || this.pendingActiveTabId !== undefined)
|
|
902
|
+
return;
|
|
903
|
+
this.clearHistoryReloadTimers(tabId);
|
|
904
|
+
for (const delayMs of [150, 1000, 3000]) {
|
|
905
|
+
const timer = setTimeout(() => {
|
|
906
|
+
this.historyReloadTimersByTabId.get(tabId)?.delete(timer);
|
|
907
|
+
void this.reloadActiveTabHistoryIfNeeded(tabId, runtime, delayMs === 3000);
|
|
908
|
+
}, delayMs);
|
|
909
|
+
timer.unref?.();
|
|
910
|
+
let timers = this.historyReloadTimersByTabId.get(tabId);
|
|
911
|
+
if (!timers) {
|
|
912
|
+
timers = new Set();
|
|
913
|
+
this.historyReloadTimersByTabId.set(tabId, timers);
|
|
914
|
+
}
|
|
915
|
+
timers.add(timer);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
async reloadActiveTabHistoryIfNeeded(tabId, runtime, finalAttempt) {
|
|
919
|
+
if (tabId !== this.activeTabId || this.pendingActiveTabId !== undefined || this.host.runtime() !== runtime)
|
|
920
|
+
return;
|
|
921
|
+
if (!this.tabIdsNeedingHistoryReload.has(tabId))
|
|
922
|
+
return;
|
|
923
|
+
await this.loadActiveSessionHistory(runtime);
|
|
924
|
+
if (finalAttempt && tabId === this.activeTabId && this.host.runtime() === runtime) {
|
|
925
|
+
this.tabIdsNeedingHistoryReload.delete(tabId);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
881
928
|
syncTabFromObservedRuntime(tabId, runtime) {
|
|
882
929
|
const tab = this.tabItems.find((item) => item.id === tabId);
|
|
883
930
|
if (!tab) {
|
|
@@ -40,6 +40,7 @@ const DEFAULT_LOOKUP_TIMEOUT_MS = 120_000;
|
|
|
40
40
|
const MAX_IMAGE_BYTES = 16 * 1024 * 1024;
|
|
41
41
|
const SILENCE_REMINDER_MIN_VIOLATION_GAP = 3;
|
|
42
42
|
const SILENCE_REMINDER_MIN_MESSAGE_GAP = 12;
|
|
43
|
+
const LOOKUP_TOOL_NAME = "lookup";
|
|
43
44
|
|
|
44
45
|
const LOOKUP_TOOL_PARAMS = Type.Object(
|
|
45
46
|
{
|
|
@@ -187,16 +188,35 @@ export default function glmCodingDiscipline(pi: ExtensionAPI) {
|
|
|
187
188
|
pi.registerTool(createLookupTool());
|
|
188
189
|
}
|
|
189
190
|
|
|
191
|
+
function syncLookupToolAvailability(modelRef: string | undefined, cwd?: string): void {
|
|
192
|
+
const activeTools = typeof pi.getActiveTools === "function" ? pi.getActiveTools() : undefined;
|
|
193
|
+
if (!Array.isArray(activeTools)) return;
|
|
194
|
+
|
|
195
|
+
const lookupEnabled = Boolean(lookupModelFromConfig(cwd));
|
|
196
|
+
const shouldExposeLookup = lookupEnabled && isGlmModel(modelRef);
|
|
197
|
+
const hasLookup = activeTools.includes(LOOKUP_TOOL_NAME);
|
|
198
|
+
|
|
199
|
+
if (shouldExposeLookup === hasLookup) return;
|
|
200
|
+
if (typeof pi.setActiveTools !== "function") return;
|
|
201
|
+
|
|
202
|
+
const nextTools = shouldExposeLookup
|
|
203
|
+
? [...activeTools, LOOKUP_TOOL_NAME]
|
|
204
|
+
: activeTools.filter((tool: unknown) => tool !== LOOKUP_TOOL_NAME);
|
|
205
|
+
pi.setActiveTools([...new Set(nextTools)]);
|
|
206
|
+
}
|
|
207
|
+
|
|
190
208
|
maybeRegisterLookupTool(process.cwd());
|
|
191
209
|
|
|
192
210
|
pi.on("session_start", async (_event: unknown, ctx: unknown) => {
|
|
193
211
|
selectedModelRef = modelRefFromContext(ctx);
|
|
194
212
|
maybeRegisterLookupTool(contextCwd(ctx));
|
|
213
|
+
syncLookupToolAvailability(selectedModelRef, contextCwd(ctx));
|
|
195
214
|
});
|
|
196
215
|
|
|
197
216
|
pi.on("model_select", async (event: { model?: unknown }, ctx: unknown) => {
|
|
198
217
|
selectedModelRef = modelRefFromModel(event.model) ?? modelRefFromContext(ctx);
|
|
199
218
|
maybeRegisterLookupTool(contextCwd(ctx));
|
|
219
|
+
syncLookupToolAvailability(selectedModelRef, contextCwd(ctx));
|
|
200
220
|
});
|
|
201
221
|
|
|
202
222
|
pi.on("before_provider_request", async (event: { payload?: unknown }, ctx: unknown) => {
|
|
@@ -273,7 +293,7 @@ export function injectCodingDisciplineIntoPayload(payload: unknown, options: { l
|
|
|
273
293
|
|
|
274
294
|
function createLookupTool() {
|
|
275
295
|
return {
|
|
276
|
-
name:
|
|
296
|
+
name: LOOKUP_TOOL_NAME,
|
|
277
297
|
label: "Lookup",
|
|
278
298
|
description: [
|
|
279
299
|
"Ask the configured vision-capable lookup model to inspect recent image/screenshot context and answer a focused visual question.",
|