adhdev 0.8.22 → 0.8.24
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/cli/index.js +1095 -270
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1095 -270
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -84,7 +84,8 @@ function normalizeConfig(raw) {
|
|
|
84
84
|
providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
|
|
85
85
|
ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
|
|
86
86
|
disableUpstream: asBoolean(parsed.disableUpstream, DEFAULT_CONFIG.disableUpstream ?? false),
|
|
87
|
-
providerDir: asOptionalString(parsed.providerDir)
|
|
87
|
+
providerDir: asOptionalString(parsed.providerDir),
|
|
88
|
+
terminalSizingMode: parsed.terminalSizingMode === "fit" ? "fit" : "measured"
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
function generateMachineId() {
|
|
@@ -232,7 +233,8 @@ var init_config = __esm({
|
|
|
232
233
|
registeredMachineId: void 0,
|
|
233
234
|
providerSettings: {},
|
|
234
235
|
ideSettings: {},
|
|
235
|
-
disableUpstream: false
|
|
236
|
+
disableUpstream: false,
|
|
237
|
+
terminalSizingMode: "measured"
|
|
236
238
|
};
|
|
237
239
|
MACHINE_ID_PREFIX = "mach_";
|
|
238
240
|
}
|
|
@@ -2457,204 +2459,97 @@ var init_status_monitor = __esm({
|
|
|
2457
2459
|
}
|
|
2458
2460
|
});
|
|
2459
2461
|
|
|
2460
|
-
// ../../oss/packages/daemon-core/src/providers/
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
this.monitor.updateConfig({
|
|
2502
|
-
approvalAlert: this.settings.approvalAlert !== false,
|
|
2503
|
-
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
2504
|
-
longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
|
|
2505
|
-
});
|
|
2506
|
-
}
|
|
2507
|
-
async onTick() {
|
|
2508
|
-
if (!this.context?.cdp?.isConnected) return;
|
|
2509
|
-
}
|
|
2510
|
-
getState() {
|
|
2511
|
-
return {
|
|
2512
|
-
type: this.type,
|
|
2513
|
-
name: this.provider.name,
|
|
2514
|
-
category: "extension",
|
|
2515
|
-
status: this.currentStatus,
|
|
2516
|
-
activeChat: this.messages.length > 0 ? {
|
|
2517
|
-
id: this.chatId || this.instanceId,
|
|
2518
|
-
title: this.chatTitle || this.agentName || this.provider.name,
|
|
2519
|
-
status: this.currentStatus,
|
|
2520
|
-
messages: this.messages,
|
|
2521
|
-
activeModal: this.activeModal,
|
|
2522
|
-
inputContent: ""
|
|
2523
|
-
} : null,
|
|
2524
|
-
currentModel: this.currentModel || void 0,
|
|
2525
|
-
currentPlan: this.currentMode || void 0,
|
|
2526
|
-
controlValues: this.controlValues,
|
|
2527
|
-
providerControls: this.provider.controls,
|
|
2528
|
-
agentStreams: this.agentStreams,
|
|
2529
|
-
instanceId: this.instanceId,
|
|
2530
|
-
lastUpdated: Date.now(),
|
|
2531
|
-
settings: this.settings,
|
|
2532
|
-
pendingEvents: this.flushEvents()
|
|
2533
|
-
};
|
|
2534
|
-
}
|
|
2535
|
-
onEvent(event, data) {
|
|
2536
|
-
if (event === "stream_update") {
|
|
2537
|
-
if (data?.streams) this.agentStreams = data.streams;
|
|
2538
|
-
if (data?.messages) this.messages = data.messages;
|
|
2539
|
-
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
2540
|
-
if (data?.model) this.currentModel = data.model;
|
|
2541
|
-
if (data?.mode) this.currentMode = data.mode;
|
|
2542
|
-
if (data?.controlValues) this.controlValues = data.controlValues;
|
|
2543
|
-
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
2544
|
-
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
2545
|
-
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
2546
|
-
if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
|
|
2547
|
-
if (data?.status) {
|
|
2548
|
-
const newStatus = data.status;
|
|
2549
|
-
this.detectTransition(newStatus, data);
|
|
2550
|
-
this.currentStatus = newStatus;
|
|
2551
|
-
}
|
|
2552
|
-
} else if (event === "stream_reset") {
|
|
2553
|
-
this.resetStreamState();
|
|
2554
|
-
} else if (event === "extension_connected") {
|
|
2555
|
-
this.ideType = data?.ideType || "";
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
dispose() {
|
|
2559
|
-
this.agentStreams = [];
|
|
2560
|
-
this.messages = [];
|
|
2561
|
-
this.monitor.reset();
|
|
2562
|
-
}
|
|
2563
|
-
/** Query UUID instanceId */
|
|
2564
|
-
getInstanceId() {
|
|
2565
|
-
return this.instanceId;
|
|
2566
|
-
}
|
|
2567
|
-
// ─── status transition detect ──────────────────────────────
|
|
2568
|
-
detectTransition(newStatus, data) {
|
|
2569
|
-
const now = Date.now();
|
|
2570
|
-
const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
|
|
2571
|
-
const lastMsg = Array.isArray(data?.messages) && data.messages.length > 0 ? data.messages[data.messages.length - 1] : null;
|
|
2572
|
-
const progressFingerprint = agentStatus === "generating" ? `${lastMsg?.role || ""}:${typeof lastMsg?.content === "string" ? lastMsg.content : JSON.stringify(lastMsg?.content || "")}`.slice(-2e3) : void 0;
|
|
2573
|
-
if (agentStatus !== this.lastAgentStatus) {
|
|
2574
|
-
if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
|
|
2575
|
-
this.generatingStartedAt = now;
|
|
2576
|
-
this.pushEvent({
|
|
2577
|
-
event: "agent:generating_started",
|
|
2578
|
-
chatTitle: this.resolveChatTitle(data),
|
|
2579
|
-
timestamp: now,
|
|
2580
|
-
ideType: this.ideType || this.type,
|
|
2581
|
-
agentType: this.type,
|
|
2582
|
-
agentName: this.agentName || this.provider.name,
|
|
2583
|
-
extensionId: this.extensionId || this.type
|
|
2584
|
-
});
|
|
2585
|
-
} else if (agentStatus === "waiting_approval") {
|
|
2586
|
-
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
2587
|
-
this.pushEvent({
|
|
2588
|
-
event: "agent:waiting_approval",
|
|
2589
|
-
chatTitle: this.resolveChatTitle(data),
|
|
2590
|
-
timestamp: now,
|
|
2591
|
-
ideType: this.ideType || this.type,
|
|
2592
|
-
agentType: this.type,
|
|
2593
|
-
agentName: this.agentName || this.provider.name,
|
|
2594
|
-
extensionId: this.extensionId || this.type,
|
|
2595
|
-
modalMessage: data?.activeModal?.message,
|
|
2596
|
-
modalButtons: data?.activeModal?.buttons
|
|
2597
|
-
});
|
|
2598
|
-
} else if (agentStatus === "idle" && (this.lastAgentStatus === "generating" || this.lastAgentStatus === "waiting_approval")) {
|
|
2599
|
-
const duration3 = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
|
|
2600
|
-
this.pushEvent({
|
|
2601
|
-
event: "agent:generating_completed",
|
|
2602
|
-
chatTitle: this.resolveChatTitle(data),
|
|
2603
|
-
duration: duration3,
|
|
2604
|
-
timestamp: now,
|
|
2605
|
-
ideType: this.ideType || this.type,
|
|
2606
|
-
agentType: this.type,
|
|
2607
|
-
agentName: this.agentName || this.provider.name,
|
|
2608
|
-
extensionId: this.extensionId || this.type
|
|
2609
|
-
});
|
|
2610
|
-
this.generatingStartedAt = 0;
|
|
2611
|
-
}
|
|
2612
|
-
this.lastAgentStatus = agentStatus;
|
|
2462
|
+
// ../../oss/packages/daemon-core/src/providers/control-effects.ts
|
|
2463
|
+
function extractProviderControlValues(controls, data) {
|
|
2464
|
+
if (!data || typeof data !== "object") return void 0;
|
|
2465
|
+
const values = {};
|
|
2466
|
+
const explicit = data.controlValues;
|
|
2467
|
+
if (explicit && typeof explicit === "object") {
|
|
2468
|
+
for (const [key, value] of Object.entries(explicit)) {
|
|
2469
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
2470
|
+
values[key] = value;
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
for (const ctrl of controls || []) {
|
|
2475
|
+
if (!ctrl.readFrom) continue;
|
|
2476
|
+
const rawValue = data[ctrl.readFrom];
|
|
2477
|
+
if (rawValue === void 0 || rawValue === null) continue;
|
|
2478
|
+
values[ctrl.id] = normalizeControlValue(rawValue);
|
|
2479
|
+
}
|
|
2480
|
+
if (data.model !== void 0 && values.model === void 0) values.model = normalizeControlValue(data.model);
|
|
2481
|
+
if (data.mode !== void 0 && values.mode === void 0) values.mode = normalizeControlValue(data.mode);
|
|
2482
|
+
return Object.keys(values).length > 0 ? values : void 0;
|
|
2483
|
+
}
|
|
2484
|
+
function normalizeProviderEffects(data) {
|
|
2485
|
+
const rawEffects = Array.isArray(data?.effects) ? data.effects : [];
|
|
2486
|
+
const effects = [];
|
|
2487
|
+
for (const raw of rawEffects) {
|
|
2488
|
+
if (!raw || typeof raw !== "object") continue;
|
|
2489
|
+
const type = raw.type;
|
|
2490
|
+
if (type === "message" && raw.message && typeof raw.message === "object") {
|
|
2491
|
+
const content = raw.message.content;
|
|
2492
|
+
if (typeof content !== "string" && !Array.isArray(content)) continue;
|
|
2493
|
+
effects.push({
|
|
2494
|
+
type: "message",
|
|
2495
|
+
id: typeof raw.id === "string" ? raw.id : void 0,
|
|
2496
|
+
when: raw.when === "turn_completed" ? "turn_completed" : "immediate",
|
|
2497
|
+
persist: raw.persist !== false,
|
|
2498
|
+
message: {
|
|
2499
|
+
role: raw.message.role === "assistant" || raw.message.role === "user" ? raw.message.role : "system",
|
|
2500
|
+
content,
|
|
2501
|
+
kind: typeof raw.message.kind === "string" ? raw.message.kind : void 0,
|
|
2502
|
+
senderName: typeof raw.message.senderName === "string" ? raw.message.senderName : void 0
|
|
2613
2503
|
}
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2504
|
+
});
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
if (type === "toast" && raw.toast && typeof raw.toast.message === "string") {
|
|
2508
|
+
effects.push({
|
|
2509
|
+
type: "toast",
|
|
2510
|
+
id: typeof raw.id === "string" ? raw.id : void 0,
|
|
2511
|
+
when: raw.when === "turn_completed" ? "turn_completed" : "immediate",
|
|
2512
|
+
persist: raw.persist !== false,
|
|
2513
|
+
toast: {
|
|
2514
|
+
level: raw.toast.level === "success" || raw.toast.level === "warning" ? raw.toast.level : "info",
|
|
2515
|
+
message: raw.toast.message
|
|
2618
2516
|
}
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
this.detectTransition("idle", {
|
|
2636
|
-
title: this.chatTitle,
|
|
2637
|
-
agentName: this.agentName,
|
|
2638
|
-
extensionId: this.extensionId,
|
|
2639
|
-
messages: this.messages
|
|
2640
|
-
});
|
|
2517
|
+
});
|
|
2518
|
+
continue;
|
|
2519
|
+
}
|
|
2520
|
+
if (type === "notification" && raw.notification && typeof raw.notification.body === "string") {
|
|
2521
|
+
effects.push({
|
|
2522
|
+
type: "notification",
|
|
2523
|
+
id: typeof raw.id === "string" ? raw.id : void 0,
|
|
2524
|
+
when: raw.when === "turn_completed" ? "turn_completed" : "immediate",
|
|
2525
|
+
persist: raw.persist !== false,
|
|
2526
|
+
notification: {
|
|
2527
|
+
title: typeof raw.notification.title === "string" ? raw.notification.title : void 0,
|
|
2528
|
+
body: raw.notification.body,
|
|
2529
|
+
level: raw.notification.level === "success" || raw.notification.level === "warning" ? raw.notification.level : "info",
|
|
2530
|
+
channels: Array.isArray(raw.notification.channels) ? raw.notification.channels.filter((channel) => channel === "bubble" || channel === "toast" || channel === "browser") : void 0,
|
|
2531
|
+
preferenceKey: raw.notification.preferenceKey === "disconnect" || raw.notification.preferenceKey === "completion" || raw.notification.preferenceKey === "approval" || raw.notification.preferenceKey === "browser" ? raw.notification.preferenceKey : void 0,
|
|
2532
|
+
bubbleContent: typeof raw.notification.bubbleContent === "string" || Array.isArray(raw.notification.bubbleContent) ? raw.notification.bubbleContent : void 0
|
|
2641
2533
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2534
|
+
});
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
return effects;
|
|
2538
|
+
}
|
|
2539
|
+
function normalizeControlValue(value) {
|
|
2540
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
2541
|
+
return value;
|
|
2542
|
+
}
|
|
2543
|
+
if (value && typeof value === "object") {
|
|
2544
|
+
if (typeof value.label === "string") return value.label;
|
|
2545
|
+
if (typeof value.name === "string") return value.name;
|
|
2546
|
+
if (typeof value.id === "string") return value.id;
|
|
2547
|
+
}
|
|
2548
|
+
return String(value);
|
|
2549
|
+
}
|
|
2550
|
+
var init_control_effects = __esm({
|
|
2551
|
+
"../../oss/packages/daemon-core/src/providers/control-effects.ts"() {
|
|
2552
|
+
"use strict";
|
|
2658
2553
|
}
|
|
2659
2554
|
});
|
|
2660
2555
|
|
|
@@ -2938,6 +2833,344 @@ var init_chat_history = __esm({
|
|
|
2938
2833
|
}
|
|
2939
2834
|
});
|
|
2940
2835
|
|
|
2836
|
+
// ../../oss/packages/daemon-core/src/providers/extension-provider-instance.ts
|
|
2837
|
+
var ExtensionProviderInstance;
|
|
2838
|
+
var init_extension_provider_instance = __esm({
|
|
2839
|
+
"../../oss/packages/daemon-core/src/providers/extension-provider-instance.ts"() {
|
|
2840
|
+
"use strict";
|
|
2841
|
+
init_status_monitor();
|
|
2842
|
+
init_control_effects();
|
|
2843
|
+
init_chat_history();
|
|
2844
|
+
ExtensionProviderInstance = class {
|
|
2845
|
+
type;
|
|
2846
|
+
category = "extension";
|
|
2847
|
+
provider;
|
|
2848
|
+
context = null;
|
|
2849
|
+
settings = {};
|
|
2850
|
+
events = [];
|
|
2851
|
+
// status
|
|
2852
|
+
currentStatus = "idle";
|
|
2853
|
+
agentStreams = [];
|
|
2854
|
+
messages = [];
|
|
2855
|
+
activeModal = null;
|
|
2856
|
+
currentModel = "";
|
|
2857
|
+
currentMode = "";
|
|
2858
|
+
controlValues = {};
|
|
2859
|
+
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
2860
|
+
runtimeMessages = [];
|
|
2861
|
+
lastAgentStatus = "idle";
|
|
2862
|
+
generatingStartedAt = 0;
|
|
2863
|
+
monitor;
|
|
2864
|
+
historyWriter;
|
|
2865
|
+
// meta
|
|
2866
|
+
instanceId;
|
|
2867
|
+
ideType = "";
|
|
2868
|
+
chatId = null;
|
|
2869
|
+
chatTitle = null;
|
|
2870
|
+
agentName = "";
|
|
2871
|
+
extensionId = "";
|
|
2872
|
+
constructor(provider) {
|
|
2873
|
+
this.type = provider.type;
|
|
2874
|
+
this.provider = provider;
|
|
2875
|
+
this.instanceId = crypto.randomUUID();
|
|
2876
|
+
this.monitor = new StatusMonitor();
|
|
2877
|
+
this.historyWriter = new ChatHistoryWriter();
|
|
2878
|
+
}
|
|
2879
|
+
// ─── Lifecycle ──────────────────────────────────
|
|
2880
|
+
async init(context) {
|
|
2881
|
+
this.context = context;
|
|
2882
|
+
this.settings = context.settings || {};
|
|
2883
|
+
this.monitor.updateConfig({
|
|
2884
|
+
approvalAlert: this.settings.approvalAlert !== false,
|
|
2885
|
+
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
2886
|
+
longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
async onTick() {
|
|
2890
|
+
if (!this.context?.cdp?.isConnected) return;
|
|
2891
|
+
}
|
|
2892
|
+
getState() {
|
|
2893
|
+
return {
|
|
2894
|
+
type: this.type,
|
|
2895
|
+
name: this.provider.name,
|
|
2896
|
+
category: "extension",
|
|
2897
|
+
status: this.currentStatus,
|
|
2898
|
+
activeChat: this.messages.length > 0 || this.runtimeMessages.length > 0 ? {
|
|
2899
|
+
id: this.chatId || this.instanceId,
|
|
2900
|
+
title: this.chatTitle || this.agentName || this.provider.name,
|
|
2901
|
+
status: this.currentStatus,
|
|
2902
|
+
messages: this.mergeConversationMessages(this.messages),
|
|
2903
|
+
activeModal: this.activeModal,
|
|
2904
|
+
inputContent: ""
|
|
2905
|
+
} : null,
|
|
2906
|
+
currentModel: this.currentModel || void 0,
|
|
2907
|
+
currentPlan: this.currentMode || void 0,
|
|
2908
|
+
controlValues: this.controlValues,
|
|
2909
|
+
providerControls: this.provider.controls,
|
|
2910
|
+
agentStreams: this.agentStreams,
|
|
2911
|
+
instanceId: this.instanceId,
|
|
2912
|
+
lastUpdated: Date.now(),
|
|
2913
|
+
settings: this.settings,
|
|
2914
|
+
pendingEvents: this.flushEvents()
|
|
2915
|
+
};
|
|
2916
|
+
}
|
|
2917
|
+
onEvent(event, data) {
|
|
2918
|
+
if (event === "stream_update") {
|
|
2919
|
+
if (data?.streams) this.agentStreams = data.streams;
|
|
2920
|
+
if (data?.messages) this.messages = data.messages;
|
|
2921
|
+
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
2922
|
+
if (data?.model) this.currentModel = data.model;
|
|
2923
|
+
if (data?.mode) this.currentMode = data.mode;
|
|
2924
|
+
const controlValues = extractProviderControlValues(this.provider.controls, data) || data?.controlValues;
|
|
2925
|
+
if (controlValues) this.controlValues = controlValues;
|
|
2926
|
+
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
2927
|
+
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
2928
|
+
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
2929
|
+
if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
|
|
2930
|
+
if (data?.status) {
|
|
2931
|
+
const newStatus = data.status;
|
|
2932
|
+
this.detectTransition(newStatus, data);
|
|
2933
|
+
this.currentStatus = newStatus;
|
|
2934
|
+
}
|
|
2935
|
+
} else if (event === "stream_reset") {
|
|
2936
|
+
this.resetStreamState();
|
|
2937
|
+
} else if (event === "extension_connected") {
|
|
2938
|
+
this.ideType = data?.ideType || "";
|
|
2939
|
+
} else if (event === "provider_state_patch" && data && typeof data === "object") {
|
|
2940
|
+
this.applyProviderResponse(data, { phase: "immediate" });
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
dispose() {
|
|
2944
|
+
this.agentStreams = [];
|
|
2945
|
+
this.messages = [];
|
|
2946
|
+
this.monitor.reset();
|
|
2947
|
+
this.appliedEffectKeys.clear();
|
|
2948
|
+
this.runtimeMessages = [];
|
|
2949
|
+
}
|
|
2950
|
+
updateSettings(newSettings) {
|
|
2951
|
+
this.settings = { ...newSettings };
|
|
2952
|
+
this.monitor.updateConfig({
|
|
2953
|
+
approvalAlert: this.settings.approvalAlert !== false,
|
|
2954
|
+
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
2955
|
+
longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
|
|
2956
|
+
});
|
|
2957
|
+
}
|
|
2958
|
+
/** Query UUID instanceId */
|
|
2959
|
+
getInstanceId() {
|
|
2960
|
+
return this.instanceId;
|
|
2961
|
+
}
|
|
2962
|
+
// ─── status transition detect ──────────────────────────────
|
|
2963
|
+
detectTransition(newStatus, data) {
|
|
2964
|
+
const now = Date.now();
|
|
2965
|
+
const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
|
|
2966
|
+
const lastMsg = Array.isArray(data?.messages) && data.messages.length > 0 ? data.messages[data.messages.length - 1] : null;
|
|
2967
|
+
const progressFingerprint = agentStatus === "generating" ? `${lastMsg?.role || ""}:${typeof lastMsg?.content === "string" ? lastMsg.content : JSON.stringify(lastMsg?.content || "")}`.slice(-2e3) : void 0;
|
|
2968
|
+
const previousStatus = this.lastAgentStatus;
|
|
2969
|
+
if (agentStatus !== this.lastAgentStatus) {
|
|
2970
|
+
if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
|
|
2971
|
+
this.generatingStartedAt = now;
|
|
2972
|
+
this.pushEvent({
|
|
2973
|
+
event: "agent:generating_started",
|
|
2974
|
+
chatTitle: this.resolveChatTitle(data),
|
|
2975
|
+
timestamp: now,
|
|
2976
|
+
ideType: this.ideType || this.type,
|
|
2977
|
+
agentType: this.type,
|
|
2978
|
+
agentName: this.agentName || this.provider.name,
|
|
2979
|
+
extensionId: this.extensionId || this.type
|
|
2980
|
+
});
|
|
2981
|
+
} else if (agentStatus === "waiting_approval") {
|
|
2982
|
+
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
2983
|
+
this.pushEvent({
|
|
2984
|
+
event: "agent:waiting_approval",
|
|
2985
|
+
chatTitle: this.resolveChatTitle(data),
|
|
2986
|
+
timestamp: now,
|
|
2987
|
+
ideType: this.ideType || this.type,
|
|
2988
|
+
agentType: this.type,
|
|
2989
|
+
agentName: this.agentName || this.provider.name,
|
|
2990
|
+
extensionId: this.extensionId || this.type,
|
|
2991
|
+
modalMessage: data?.activeModal?.message,
|
|
2992
|
+
modalButtons: data?.activeModal?.buttons
|
|
2993
|
+
});
|
|
2994
|
+
} else if (agentStatus === "idle" && (this.lastAgentStatus === "generating" || this.lastAgentStatus === "waiting_approval")) {
|
|
2995
|
+
const duration3 = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
|
|
2996
|
+
this.pushEvent({
|
|
2997
|
+
event: "agent:generating_completed",
|
|
2998
|
+
chatTitle: this.resolveChatTitle(data),
|
|
2999
|
+
duration: duration3,
|
|
3000
|
+
timestamp: now,
|
|
3001
|
+
ideType: this.ideType || this.type,
|
|
3002
|
+
agentType: this.type,
|
|
3003
|
+
agentName: this.agentName || this.provider.name,
|
|
3004
|
+
extensionId: this.extensionId || this.type
|
|
3005
|
+
});
|
|
3006
|
+
this.generatingStartedAt = 0;
|
|
3007
|
+
}
|
|
3008
|
+
this.lastAgentStatus = agentStatus;
|
|
3009
|
+
}
|
|
3010
|
+
this.applyProviderResponse(data, {
|
|
3011
|
+
phase: agentStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
|
|
3012
|
+
});
|
|
3013
|
+
const agentKey = `${this.type}:ext`;
|
|
3014
|
+
const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
|
|
3015
|
+
for (const me of monitorEvents) {
|
|
3016
|
+
this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
pushEvent(event) {
|
|
3020
|
+
this.events.push(event);
|
|
3021
|
+
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
3022
|
+
}
|
|
3023
|
+
applyProviderResponse(data, options) {
|
|
3024
|
+
if (!data || typeof data !== "object") return;
|
|
3025
|
+
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
3026
|
+
if (controlValues) this.controlValues = { ...this.controlValues, ...controlValues };
|
|
3027
|
+
const effects = normalizeProviderEffects(data);
|
|
3028
|
+
for (const effect of effects) {
|
|
3029
|
+
const effectWhen = effect.when || "immediate";
|
|
3030
|
+
if (effectWhen === "turn_completed" && options.phase !== "turn_completed") continue;
|
|
3031
|
+
if (effectWhen === "immediate" && options.phase === "turn_completed") continue;
|
|
3032
|
+
const effectKey = this.getEffectDedupKey(effect);
|
|
3033
|
+
if (this.appliedEffectKeys.has(effectKey)) continue;
|
|
3034
|
+
this.appliedEffectKeys.add(effectKey);
|
|
3035
|
+
if (effect.persist !== false) {
|
|
3036
|
+
const persisted = this.getPersistedEffectContent(effect);
|
|
3037
|
+
if (persisted) this.appendRuntimeSystemMessage(persisted, effectKey);
|
|
3038
|
+
}
|
|
3039
|
+
if (effect.type === "message" && effect.message) {
|
|
3040
|
+
this.pushEvent({
|
|
3041
|
+
event: "provider:message",
|
|
3042
|
+
timestamp: Date.now(),
|
|
3043
|
+
content: typeof effect.message.content === "string" ? effect.message.content : JSON.stringify(effect.message.content),
|
|
3044
|
+
role: effect.message.role || "system",
|
|
3045
|
+
kind: effect.message.kind,
|
|
3046
|
+
senderName: effect.message.senderName
|
|
3047
|
+
});
|
|
3048
|
+
} else if (effect.type === "toast" && effect.toast) {
|
|
3049
|
+
this.pushEvent({
|
|
3050
|
+
event: "provider:toast",
|
|
3051
|
+
effectId: effect.id || effectKey,
|
|
3052
|
+
timestamp: Date.now(),
|
|
3053
|
+
message: effect.toast.message,
|
|
3054
|
+
level: effect.toast.level || "info"
|
|
3055
|
+
});
|
|
3056
|
+
} else if (effect.type === "notification" && effect.notification) {
|
|
3057
|
+
this.pushEvent({
|
|
3058
|
+
event: "provider:notification",
|
|
3059
|
+
effectId: effect.id || effectKey,
|
|
3060
|
+
timestamp: Date.now(),
|
|
3061
|
+
title: effect.notification.title,
|
|
3062
|
+
message: effect.notification.body,
|
|
3063
|
+
content: typeof effect.notification.bubbleContent === "string" ? effect.notification.bubbleContent : effect.notification.body,
|
|
3064
|
+
level: effect.notification.level || "info",
|
|
3065
|
+
channels: effect.notification.channels || ["toast"],
|
|
3066
|
+
preferenceKey: effect.notification.preferenceKey
|
|
3067
|
+
});
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
|
|
3072
|
+
const normalizedContent = String(content || "").trim();
|
|
3073
|
+
if (!normalizedContent) return;
|
|
3074
|
+
if (this.runtimeMessages.some((entry) => entry.key === dedupKey)) return;
|
|
3075
|
+
this.runtimeMessages.push({
|
|
3076
|
+
key: dedupKey,
|
|
3077
|
+
message: {
|
|
3078
|
+
role: "system",
|
|
3079
|
+
senderName: "System",
|
|
3080
|
+
content: normalizedContent,
|
|
3081
|
+
receivedAt,
|
|
3082
|
+
timestamp: receivedAt
|
|
3083
|
+
}
|
|
3084
|
+
});
|
|
3085
|
+
if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
3086
|
+
this.historyWriter.appendNewMessages(
|
|
3087
|
+
this.type,
|
|
3088
|
+
[{
|
|
3089
|
+
role: "system",
|
|
3090
|
+
senderName: "System",
|
|
3091
|
+
content: normalizedContent,
|
|
3092
|
+
kind: "system",
|
|
3093
|
+
receivedAt,
|
|
3094
|
+
historyDedupKey: dedupKey
|
|
3095
|
+
}],
|
|
3096
|
+
this.chatTitle || this.agentName || this.provider.name,
|
|
3097
|
+
this.instanceId,
|
|
3098
|
+
this.chatId || this.instanceId
|
|
3099
|
+
);
|
|
3100
|
+
}
|
|
3101
|
+
mergeConversationMessages(messages) {
|
|
3102
|
+
if (this.runtimeMessages.length === 0) return messages;
|
|
3103
|
+
return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b) => {
|
|
3104
|
+
const aTime = a.message.receivedAt || a.message.timestamp || 0;
|
|
3105
|
+
const bTime = b.message.receivedAt || b.message.timestamp || 0;
|
|
3106
|
+
if (aTime !== bTime) return aTime - bTime;
|
|
3107
|
+
return a.index - b.index;
|
|
3108
|
+
}).map((entry) => entry.message);
|
|
3109
|
+
}
|
|
3110
|
+
getPersistedEffectContent(effect) {
|
|
3111
|
+
if (effect.type === "message") {
|
|
3112
|
+
return typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
|
|
3113
|
+
}
|
|
3114
|
+
if (effect.type === "toast") {
|
|
3115
|
+
return effect.toast?.message || null;
|
|
3116
|
+
}
|
|
3117
|
+
if (effect.type === "notification") {
|
|
3118
|
+
if (typeof effect.notification?.bubbleContent === "string") return effect.notification.bubbleContent;
|
|
3119
|
+
if (typeof effect.notification?.title === "string" && effect.notification.title.trim()) {
|
|
3120
|
+
return `${effect.notification.title}
|
|
3121
|
+
${effect.notification.body || ""}`.trim();
|
|
3122
|
+
}
|
|
3123
|
+
return effect.notification?.body || null;
|
|
3124
|
+
}
|
|
3125
|
+
return null;
|
|
3126
|
+
}
|
|
3127
|
+
getEffectDedupKey(effect) {
|
|
3128
|
+
if (effect.id) return `provider_effect:${effect.id}`;
|
|
3129
|
+
if (effect.type === "message") {
|
|
3130
|
+
return `provider_effect:message:${typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "")}`;
|
|
3131
|
+
}
|
|
3132
|
+
if (effect.type === "notification") {
|
|
3133
|
+
return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
|
|
3134
|
+
}
|
|
3135
|
+
return `provider_effect:toast:${effect.toast?.message || ""}`;
|
|
3136
|
+
}
|
|
3137
|
+
flushEvents() {
|
|
3138
|
+
const events = [...this.events];
|
|
3139
|
+
this.events = [];
|
|
3140
|
+
return events;
|
|
3141
|
+
}
|
|
3142
|
+
resolveChatTitle(data) {
|
|
3143
|
+
const title = typeof data?.title === "string" && data.title.trim() ? data.title.trim() : this.chatTitle;
|
|
3144
|
+
return title || this.agentName || this.provider.name;
|
|
3145
|
+
}
|
|
3146
|
+
resetStreamState() {
|
|
3147
|
+
if (this.currentStatus !== "idle") {
|
|
3148
|
+
this.detectTransition("idle", {
|
|
3149
|
+
title: this.chatTitle,
|
|
3150
|
+
agentName: this.agentName,
|
|
3151
|
+
extensionId: this.extensionId,
|
|
3152
|
+
messages: this.messages
|
|
3153
|
+
});
|
|
3154
|
+
}
|
|
3155
|
+
this.agentStreams = [];
|
|
3156
|
+
this.messages = [];
|
|
3157
|
+
this.activeModal = null;
|
|
3158
|
+
this.currentModel = "";
|
|
3159
|
+
this.currentMode = "";
|
|
3160
|
+
this.controlValues = {};
|
|
3161
|
+
this.currentStatus = "idle";
|
|
3162
|
+
this.chatId = null;
|
|
3163
|
+
this.chatTitle = null;
|
|
3164
|
+
this.agentName = "";
|
|
3165
|
+
this.extensionId = "";
|
|
3166
|
+
this.lastAgentStatus = "idle";
|
|
3167
|
+
this.generatingStartedAt = 0;
|
|
3168
|
+
this.monitor.reset();
|
|
3169
|
+
}
|
|
3170
|
+
};
|
|
3171
|
+
}
|
|
3172
|
+
});
|
|
3173
|
+
|
|
2941
3174
|
// ../../oss/packages/daemon-core/src/providers/ide-provider-instance.ts
|
|
2942
3175
|
var crypto2, IdeProviderInstance;
|
|
2943
3176
|
var init_ide_provider_instance = __esm({
|
|
@@ -2948,6 +3181,7 @@ var init_ide_provider_instance = __esm({
|
|
|
2948
3181
|
init_status_monitor();
|
|
2949
3182
|
init_chat_history();
|
|
2950
3183
|
init_logger();
|
|
3184
|
+
init_control_effects();
|
|
2951
3185
|
IdeProviderInstance = class {
|
|
2952
3186
|
type;
|
|
2953
3187
|
category = "ide";
|
|
@@ -2965,6 +3199,8 @@ var init_ide_provider_instance = __esm({
|
|
|
2965
3199
|
monitor;
|
|
2966
3200
|
historyWriter;
|
|
2967
3201
|
autoApproveBusy = false;
|
|
3202
|
+
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
3203
|
+
runtimeMessages = [];
|
|
2968
3204
|
// IDE meta
|
|
2969
3205
|
ideVersion = "";
|
|
2970
3206
|
instanceId;
|
|
@@ -3025,7 +3261,7 @@ var init_ide_provider_instance = __esm({
|
|
|
3025
3261
|
id: this.cachedChat.id || "active_session",
|
|
3026
3262
|
title: this.cachedChat.title || this.type,
|
|
3027
3263
|
status: this.cachedChat.status || this.currentStatus,
|
|
3028
|
-
messages: this.cachedChat.messages || [],
|
|
3264
|
+
messages: this.mergeConversationMessages(this.cachedChat.messages || []),
|
|
3029
3265
|
activeModal: this.cachedChat.activeModal || null,
|
|
3030
3266
|
inputContent: this.cachedChat.inputContent || ""
|
|
3031
3267
|
} : null,
|
|
@@ -3065,6 +3301,13 @@ var init_ide_provider_instance = __esm({
|
|
|
3065
3301
|
for (const ext of this.extensions.values()) {
|
|
3066
3302
|
ext.onEvent("stream_reset");
|
|
3067
3303
|
}
|
|
3304
|
+
} else if (event === "provider_state_patch" && data && typeof data === "object") {
|
|
3305
|
+
const extType = typeof data.extensionType === "string" ? data.extensionType : "";
|
|
3306
|
+
if (extType && this.extensions.has(extType)) {
|
|
3307
|
+
this.extensions.get(extType).onEvent("provider_state_patch", data);
|
|
3308
|
+
} else {
|
|
3309
|
+
this.applyProviderResponse(data, { phase: "immediate" });
|
|
3310
|
+
}
|
|
3068
3311
|
}
|
|
3069
3312
|
}
|
|
3070
3313
|
dispose() {
|
|
@@ -3072,11 +3315,21 @@ var init_ide_provider_instance = __esm({
|
|
|
3072
3315
|
this.lastAgentStatuses.clear();
|
|
3073
3316
|
this.generatingStartedAt.clear();
|
|
3074
3317
|
this.monitor.reset();
|
|
3318
|
+
this.appliedEffectKeys.clear();
|
|
3319
|
+
this.runtimeMessages = [];
|
|
3075
3320
|
for (const ext of this.extensions.values()) {
|
|
3076
3321
|
ext.dispose();
|
|
3077
3322
|
}
|
|
3078
3323
|
this.extensions.clear();
|
|
3079
3324
|
}
|
|
3325
|
+
updateSettings(newSettings) {
|
|
3326
|
+
this.settings = { ...newSettings };
|
|
3327
|
+
this.monitor.updateConfig({
|
|
3328
|
+
approvalAlert: this.settings.approvalAlert !== false,
|
|
3329
|
+
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
3330
|
+
longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
|
|
3331
|
+
});
|
|
3332
|
+
}
|
|
3080
3333
|
// ─── Extension manage ─────────────────────────────
|
|
3081
3334
|
/** Extension Instance add */
|
|
3082
3335
|
async addExtension(provider, settings) {
|
|
@@ -3189,6 +3442,8 @@ var init_ide_provider_instance = __esm({
|
|
|
3189
3442
|
raw.messages = raw.messages.filter((m) => !hiddenKinds.has(m.kind));
|
|
3190
3443
|
}
|
|
3191
3444
|
}
|
|
3445
|
+
const controlValues = extractProviderControlValues(this.provider.controls, raw);
|
|
3446
|
+
if (controlValues) raw.controlValues = controlValues;
|
|
3192
3447
|
this.cachedChat = { ...raw, activeModal };
|
|
3193
3448
|
this.detectAgentTransitions(raw, now);
|
|
3194
3449
|
if (raw.messages?.length > 0) {
|
|
@@ -3255,6 +3510,9 @@ var init_ide_provider_instance = __esm({
|
|
|
3255
3510
|
}
|
|
3256
3511
|
this.lastAgentStatuses.set(agentKey, agentStatus);
|
|
3257
3512
|
}
|
|
3513
|
+
this.applyProviderResponse(chatData, {
|
|
3514
|
+
phase: agentStatus === "idle" && (lastStatus === "generating" || lastStatus === "waiting_approval") ? "turn_completed" : "immediate"
|
|
3515
|
+
});
|
|
3258
3516
|
if (agentStatus === "waiting_approval" && this.settings.autoApprove && !this.autoApproveBusy) {
|
|
3259
3517
|
this.autoApproveViaScript(chatData);
|
|
3260
3518
|
}
|
|
@@ -3267,6 +3525,136 @@ var init_ide_provider_instance = __esm({
|
|
|
3267
3525
|
this.events.push(event);
|
|
3268
3526
|
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
3269
3527
|
}
|
|
3528
|
+
applyProviderResponse(data, options) {
|
|
3529
|
+
if (!data || typeof data !== "object") return;
|
|
3530
|
+
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
3531
|
+
if (controlValues) {
|
|
3532
|
+
this.cachedChat = {
|
|
3533
|
+
...this.cachedChat || {},
|
|
3534
|
+
...data,
|
|
3535
|
+
controlValues: { ...this.cachedChat?.controlValues || {}, ...controlValues }
|
|
3536
|
+
};
|
|
3537
|
+
}
|
|
3538
|
+
const effects = normalizeProviderEffects(data);
|
|
3539
|
+
for (const effect of effects) {
|
|
3540
|
+
const effectWhen = effect.when || "immediate";
|
|
3541
|
+
if (effectWhen === "turn_completed" && options.phase !== "turn_completed") continue;
|
|
3542
|
+
if (effectWhen === "immediate" && options.phase === "turn_completed") continue;
|
|
3543
|
+
const effectKey = this.getEffectDedupKey(effect);
|
|
3544
|
+
if (this.appliedEffectKeys.has(effectKey)) continue;
|
|
3545
|
+
this.appliedEffectKeys.add(effectKey);
|
|
3546
|
+
if (effect.persist !== false) {
|
|
3547
|
+
const persisted = this.getPersistedEffectContent(effect);
|
|
3548
|
+
if (persisted) this.appendRuntimeSystemMessage(persisted, effectKey);
|
|
3549
|
+
}
|
|
3550
|
+
if (effect.type === "message" && effect.message) {
|
|
3551
|
+
this.pushEvent({
|
|
3552
|
+
event: "provider:message",
|
|
3553
|
+
timestamp: Date.now(),
|
|
3554
|
+
content: typeof effect.message.content === "string" ? effect.message.content : JSON.stringify(effect.message.content),
|
|
3555
|
+
role: effect.message.role || "system",
|
|
3556
|
+
kind: effect.message.kind,
|
|
3557
|
+
senderName: effect.message.senderName
|
|
3558
|
+
});
|
|
3559
|
+
} else if (effect.type === "toast" && effect.toast) {
|
|
3560
|
+
this.pushEvent({
|
|
3561
|
+
event: "provider:toast",
|
|
3562
|
+
effectId: effect.id || effectKey,
|
|
3563
|
+
timestamp: Date.now(),
|
|
3564
|
+
message: effect.toast.message,
|
|
3565
|
+
level: effect.toast.level || "info"
|
|
3566
|
+
});
|
|
3567
|
+
} else if (effect.type === "notification" && effect.notification) {
|
|
3568
|
+
this.pushEvent({
|
|
3569
|
+
event: "provider:notification",
|
|
3570
|
+
effectId: effect.id || effectKey,
|
|
3571
|
+
timestamp: Date.now(),
|
|
3572
|
+
title: effect.notification.title,
|
|
3573
|
+
message: effect.notification.body,
|
|
3574
|
+
content: typeof effect.notification.bubbleContent === "string" ? effect.notification.bubbleContent : effect.notification.body,
|
|
3575
|
+
level: effect.notification.level || "info",
|
|
3576
|
+
channels: effect.notification.channels || ["toast"],
|
|
3577
|
+
preferenceKey: effect.notification.preferenceKey
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
|
|
3583
|
+
const normalizedContent = String(content || "").trim();
|
|
3584
|
+
if (!normalizedContent) return;
|
|
3585
|
+
if (this.runtimeMessages.some((entry) => entry.key === dedupKey)) return;
|
|
3586
|
+
if (!this.cachedChat) {
|
|
3587
|
+
this.cachedChat = {
|
|
3588
|
+
id: "active_session",
|
|
3589
|
+
title: this.provider.name,
|
|
3590
|
+
status: this.currentStatus,
|
|
3591
|
+
messages: [],
|
|
3592
|
+
activeModal: null,
|
|
3593
|
+
inputContent: ""
|
|
3594
|
+
};
|
|
3595
|
+
}
|
|
3596
|
+
this.runtimeMessages.push({
|
|
3597
|
+
key: dedupKey,
|
|
3598
|
+
message: {
|
|
3599
|
+
role: "system",
|
|
3600
|
+
senderName: "System",
|
|
3601
|
+
content: normalizedContent,
|
|
3602
|
+
receivedAt,
|
|
3603
|
+
timestamp: receivedAt
|
|
3604
|
+
}
|
|
3605
|
+
});
|
|
3606
|
+
if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
3607
|
+
this.historyWriter.appendNewMessages(
|
|
3608
|
+
this.type,
|
|
3609
|
+
[{
|
|
3610
|
+
role: "system",
|
|
3611
|
+
senderName: "System",
|
|
3612
|
+
content: normalizedContent,
|
|
3613
|
+
kind: "system",
|
|
3614
|
+
receivedAt,
|
|
3615
|
+
historyDedupKey: dedupKey
|
|
3616
|
+
}],
|
|
3617
|
+
this.cachedChat?.title || this.provider.name,
|
|
3618
|
+
this.instanceId,
|
|
3619
|
+
this.cachedChat?.id || this.instanceId
|
|
3620
|
+
);
|
|
3621
|
+
}
|
|
3622
|
+
mergeConversationMessages(messages) {
|
|
3623
|
+
if (this.runtimeMessages.length === 0) return messages;
|
|
3624
|
+
return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b) => {
|
|
3625
|
+
const aTime = a.message.receivedAt || a.message.timestamp || 0;
|
|
3626
|
+
const bTime = b.message.receivedAt || b.message.timestamp || 0;
|
|
3627
|
+
if (aTime !== bTime) return aTime - bTime;
|
|
3628
|
+
return a.index - b.index;
|
|
3629
|
+
}).map((entry) => entry.message);
|
|
3630
|
+
}
|
|
3631
|
+
getPersistedEffectContent(effect) {
|
|
3632
|
+
if (effect.type === "message") {
|
|
3633
|
+
return typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
|
|
3634
|
+
}
|
|
3635
|
+
if (effect.type === "toast") {
|
|
3636
|
+
return effect.toast?.message || null;
|
|
3637
|
+
}
|
|
3638
|
+
if (effect.type === "notification") {
|
|
3639
|
+
if (typeof effect.notification?.bubbleContent === "string") return effect.notification.bubbleContent;
|
|
3640
|
+
if (typeof effect.notification?.title === "string" && effect.notification.title.trim()) {
|
|
3641
|
+
return `${effect.notification.title}
|
|
3642
|
+
${effect.notification.body || ""}`.trim();
|
|
3643
|
+
}
|
|
3644
|
+
return effect.notification?.body || null;
|
|
3645
|
+
}
|
|
3646
|
+
return null;
|
|
3647
|
+
}
|
|
3648
|
+
getEffectDedupKey(effect) {
|
|
3649
|
+
if (effect.id) return `provider_effect:${effect.id}`;
|
|
3650
|
+
if (effect.type === "message") {
|
|
3651
|
+
return `provider_effect:message:${typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "")}`;
|
|
3652
|
+
}
|
|
3653
|
+
if (effect.type === "notification") {
|
|
3654
|
+
return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
|
|
3655
|
+
}
|
|
3656
|
+
return `provider_effect:toast:${effect.toast?.message || ""}`;
|
|
3657
|
+
}
|
|
3270
3658
|
flushEvents() {
|
|
3271
3659
|
const events = [...this.events];
|
|
3272
3660
|
this.events = [];
|
|
@@ -5388,7 +5776,56 @@ function handleSetProviderSetting(h, args) {
|
|
|
5388
5776
|
}
|
|
5389
5777
|
return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
|
|
5390
5778
|
}
|
|
5391
|
-
|
|
5779
|
+
function normalizeProviderScriptArgs(args) {
|
|
5780
|
+
const normalizedArgs = { ...args || {} };
|
|
5781
|
+
for (const key of ["mode", "model", "message", "action", "button", "text", "sessionId", "value"]) {
|
|
5782
|
+
if (key in normalizedArgs && !(key.toUpperCase() in normalizedArgs)) {
|
|
5783
|
+
normalizedArgs[key.toUpperCase()] = normalizedArgs[key];
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
return normalizedArgs;
|
|
5787
|
+
}
|
|
5788
|
+
function parseScriptResult(result) {
|
|
5789
|
+
if (typeof result === "string") {
|
|
5790
|
+
try {
|
|
5791
|
+
const parsed = JSON.parse(result);
|
|
5792
|
+
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
5793
|
+
return { success: false, payload: parsed };
|
|
5794
|
+
}
|
|
5795
|
+
return { success: true, payload: parsed };
|
|
5796
|
+
} catch {
|
|
5797
|
+
return { success: true, payload: { result } };
|
|
5798
|
+
}
|
|
5799
|
+
}
|
|
5800
|
+
if (result && typeof result === "object" && result.success === false) {
|
|
5801
|
+
return { success: false, payload: result };
|
|
5802
|
+
}
|
|
5803
|
+
return { success: true, payload: result };
|
|
5804
|
+
}
|
|
5805
|
+
function getCliScriptCommand(payload) {
|
|
5806
|
+
if (!payload || typeof payload !== "object") return null;
|
|
5807
|
+
if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
|
|
5808
|
+
return { type: "send_message", text: payload.sendMessage.trim() };
|
|
5809
|
+
}
|
|
5810
|
+
const command = payload.command;
|
|
5811
|
+
if (!command || typeof command !== "object") return null;
|
|
5812
|
+
if (command.type !== "send_message") return null;
|
|
5813
|
+
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
5814
|
+
if (!text) return null;
|
|
5815
|
+
return { type: "send_message", text };
|
|
5816
|
+
}
|
|
5817
|
+
function applyProviderPatch(h, args, payload) {
|
|
5818
|
+
if (!payload || typeof payload !== "object") return;
|
|
5819
|
+
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
5820
|
+
const targetSession = targetSessionId ? h.ctx.sessionRegistry?.get(targetSessionId) : void 0;
|
|
5821
|
+
const instanceKey = targetSession?.instanceKey || targetSessionId;
|
|
5822
|
+
if (!instanceKey) return;
|
|
5823
|
+
h.ctx.instanceManager?.sendEvent(instanceKey, "provider_state_patch", {
|
|
5824
|
+
...payload,
|
|
5825
|
+
extensionType: targetSession?.transport === "cdp-webview" ? targetSession.providerType : void 0
|
|
5826
|
+
});
|
|
5827
|
+
}
|
|
5828
|
+
async function executeProviderScript(h, args, scriptName) {
|
|
5392
5829
|
const { agentType, ideType } = args || {};
|
|
5393
5830
|
if (!agentType) return { success: false, error: "agentType is required" };
|
|
5394
5831
|
const loader = h.ctx.providerLoader;
|
|
@@ -5401,13 +5838,29 @@ async function handleExtensionScript(h, args, scriptName) {
|
|
|
5401
5838
|
if (!provider.scripts?.[actualScriptName]) {
|
|
5402
5839
|
return { success: false, error: `Script '${actualScriptName}' not available for ${agentType}` };
|
|
5403
5840
|
}
|
|
5404
|
-
const
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
if (
|
|
5408
|
-
|
|
5841
|
+
const normalizedArgs = normalizeProviderScriptArgs(args);
|
|
5842
|
+
if (provider.category === "cli") {
|
|
5843
|
+
const adapter = h.getCliAdapter(args?.targetSessionId || agentType);
|
|
5844
|
+
if (!adapter?.invokeScript) {
|
|
5845
|
+
return { success: false, error: `CLI adapter does not support script '${actualScriptName}'` };
|
|
5846
|
+
}
|
|
5847
|
+
try {
|
|
5848
|
+
const raw = await adapter.invokeScript(actualScriptName, normalizedArgs);
|
|
5849
|
+
const parsed = parseScriptResult(raw);
|
|
5850
|
+
if (!parsed.success) {
|
|
5851
|
+
return { success: false, ...parsed.payload || {} };
|
|
5852
|
+
}
|
|
5853
|
+
const cliCommand = getCliScriptCommand(parsed.payload);
|
|
5854
|
+
if (cliCommand?.type === "send_message" && cliCommand.text) {
|
|
5855
|
+
await adapter.sendMessage(cliCommand.text);
|
|
5856
|
+
}
|
|
5857
|
+
applyProviderPatch(h, args, parsed.payload);
|
|
5858
|
+
return { success: true, ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload } };
|
|
5859
|
+
} catch (e) {
|
|
5860
|
+
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
5409
5861
|
}
|
|
5410
5862
|
}
|
|
5863
|
+
const scriptFn = provider.scripts[actualScriptName];
|
|
5411
5864
|
const scriptCode = scriptFn(normalizedArgs);
|
|
5412
5865
|
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
5413
5866
|
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || agentType : h.currentSession?.cdpManagerKey || h.currentManagerKey || ideType;
|
|
@@ -5461,16 +5914,29 @@ async function handleExtensionScript(h, args, scriptName) {
|
|
|
5461
5914
|
if (typeof result === "string") {
|
|
5462
5915
|
try {
|
|
5463
5916
|
const parsed = JSON.parse(result);
|
|
5917
|
+
applyProviderPatch(h, args, parsed);
|
|
5918
|
+
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
5919
|
+
return { success: false, ...parsed };
|
|
5920
|
+
}
|
|
5464
5921
|
return { success: true, ...parsed };
|
|
5465
5922
|
} catch {
|
|
5466
5923
|
return { success: true, result };
|
|
5467
5924
|
}
|
|
5468
5925
|
}
|
|
5926
|
+
applyProviderPatch(h, args, result);
|
|
5469
5927
|
return { success: true, result };
|
|
5470
5928
|
} catch (e) {
|
|
5471
5929
|
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
5472
5930
|
}
|
|
5473
5931
|
}
|
|
5932
|
+
async function handleExtensionScript(h, args, scriptName) {
|
|
5933
|
+
return executeProviderScript(h, args, scriptName);
|
|
5934
|
+
}
|
|
5935
|
+
async function handleProviderScript(h, args) {
|
|
5936
|
+
const scriptName = typeof args?.scriptName === "string" ? args.scriptName.trim() : "";
|
|
5937
|
+
if (!scriptName) return { success: false, error: "scriptName is required" };
|
|
5938
|
+
return executeProviderScript(h, args, scriptName);
|
|
5939
|
+
}
|
|
5474
5940
|
function handleGetIdeExtensions(h, args) {
|
|
5475
5941
|
const { ideType } = args || {};
|
|
5476
5942
|
const loader = h.ctx.providerLoader;
|
|
@@ -5994,6 +6460,8 @@ var init_handler = __esm({
|
|
|
5994
6460
|
case "set_ide_extension":
|
|
5995
6461
|
return handleSetIdeExtension(this, args);
|
|
5996
6462
|
// ─── Extension Model / Mode Control (stream-commands.ts) ──────────
|
|
6463
|
+
case "invoke_provider_script":
|
|
6464
|
+
return handleProviderScript(this, args);
|
|
5997
6465
|
case "list_extension_models":
|
|
5998
6466
|
return handleExtensionScript(this, args, "listModels");
|
|
5999
6467
|
case "set_extension_model":
|
|
@@ -6678,6 +7146,53 @@ function stripTerminalNoise(str) {
|
|
|
6678
7146
|
function sanitizeTerminalText(str) {
|
|
6679
7147
|
return stripTerminalNoise(stripAnsi(str));
|
|
6680
7148
|
}
|
|
7149
|
+
function splitCliScreenLines(text) {
|
|
7150
|
+
return String(text || "").replace(/\u0007/g, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/\s+$/, ""));
|
|
7151
|
+
}
|
|
7152
|
+
function isPromptLikeCliLine(line) {
|
|
7153
|
+
const trimmed = String(line || "").trim();
|
|
7154
|
+
if (!trimmed) return false;
|
|
7155
|
+
return /^[❯›>]\s*(?:$|\S.*)$/.test(trimmed);
|
|
7156
|
+
}
|
|
7157
|
+
function buildCliScreenSnapshot(text) {
|
|
7158
|
+
const normalizedText = String(text || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
7159
|
+
const rawLines = splitCliScreenLines(normalizedText);
|
|
7160
|
+
const lines = rawLines.map((line, index, arr) => {
|
|
7161
|
+
const trimmed = String(line || "").trim();
|
|
7162
|
+
return {
|
|
7163
|
+
index,
|
|
7164
|
+
fromTop: index,
|
|
7165
|
+
fromBottom: arr.length - index - 1,
|
|
7166
|
+
text: line,
|
|
7167
|
+
trimmed,
|
|
7168
|
+
isEmpty: trimmed.length === 0
|
|
7169
|
+
};
|
|
7170
|
+
});
|
|
7171
|
+
const nonEmptyLines = lines.filter((line) => !line.isEmpty);
|
|
7172
|
+
const firstNonEmptyLine = nonEmptyLines[0] ?? null;
|
|
7173
|
+
const lastNonEmptyLine = nonEmptyLines[nonEmptyLines.length - 1] ?? null;
|
|
7174
|
+
let promptLineIndex = -1;
|
|
7175
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
7176
|
+
if (isPromptLikeCliLine(lines[i].text)) {
|
|
7177
|
+
promptLineIndex = i;
|
|
7178
|
+
break;
|
|
7179
|
+
}
|
|
7180
|
+
}
|
|
7181
|
+
return {
|
|
7182
|
+
text: normalizedText,
|
|
7183
|
+
lineCount: lines.length,
|
|
7184
|
+
lines,
|
|
7185
|
+
nonEmptyLines,
|
|
7186
|
+
firstNonEmptyLineIndex: firstNonEmptyLine?.index ?? -1,
|
|
7187
|
+
lastNonEmptyLineIndex: lastNonEmptyLine?.index ?? -1,
|
|
7188
|
+
firstNonEmptyLine,
|
|
7189
|
+
lastNonEmptyLine,
|
|
7190
|
+
promptLineIndex,
|
|
7191
|
+
promptLine: promptLineIndex >= 0 ? lines[promptLineIndex] : null,
|
|
7192
|
+
linesAbovePrompt: promptLineIndex >= 0 ? lines.slice(0, promptLineIndex) : [...lines],
|
|
7193
|
+
linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
|
|
7194
|
+
};
|
|
7195
|
+
}
|
|
6681
7196
|
function computeTerminalQueryTail(buffer) {
|
|
6682
7197
|
const prefixes = ["\x1B[6n", "\x1B[?6n"];
|
|
6683
7198
|
const maxLength = prefixes.reduce((n, value) => Math.max(n, value.length), 0) - 1;
|
|
@@ -6919,7 +7434,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
6919
7434
|
ready = false;
|
|
6920
7435
|
startupBuffer = "";
|
|
6921
7436
|
startupParseGate = false;
|
|
7437
|
+
startupSettleTimer = null;
|
|
6922
7438
|
spawnAt = 0;
|
|
7439
|
+
startupFirstOutputAt = 0;
|
|
6923
7440
|
// PTY I/O
|
|
6924
7441
|
onPtyDataCallback = null;
|
|
6925
7442
|
pendingOutputParseBuffer = "";
|
|
@@ -6960,6 +7477,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
6960
7477
|
statusHistory = [];
|
|
6961
7478
|
// ─── CLI Scripts (script-based parsing) ───
|
|
6962
7479
|
cliScripts;
|
|
7480
|
+
runtimeSettings = {};
|
|
6963
7481
|
/** Full accumulated ANSI-stripped PTY output */
|
|
6964
7482
|
accumulatedBuffer = "";
|
|
6965
7483
|
/** Full accumulated raw PTY output (with ANSI) */
|
|
@@ -6974,14 +7492,15 @@ var init_provider_cli_adapter = __esm({
|
|
|
6974
7492
|
traceSessionId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
6975
7493
|
static MAX_TRACE_ENTRIES = 250;
|
|
6976
7494
|
providerResolutionMeta;
|
|
6977
|
-
static IDLE_FINISH_CONFIRM_MS =
|
|
7495
|
+
static IDLE_FINISH_CONFIRM_MS = 2e3;
|
|
7496
|
+
static STATUS_ACTIVITY_HOLD_MS = 2e3;
|
|
6978
7497
|
static FINISH_RETRY_DELAY_MS = 300;
|
|
6979
7498
|
static MAX_FINISH_RETRIES = 2;
|
|
6980
7499
|
syncMessageViews() {
|
|
6981
7500
|
this.messages = [...this.committedMessages];
|
|
6982
7501
|
this.structuredMessages = [...this.committedMessages];
|
|
6983
7502
|
}
|
|
6984
|
-
|
|
7503
|
+
hydrateParsedMessages(parsedMessages, scope) {
|
|
6985
7504
|
const referenceMessages = [...this.committedMessages];
|
|
6986
7505
|
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
6987
7506
|
const now = Date.now();
|
|
@@ -7014,13 +7533,30 @@ var init_provider_cli_adapter = __esm({
|
|
|
7014
7533
|
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
7015
7534
|
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
7016
7535
|
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
7536
|
+
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : this.lastOutputAt || scope?.startedAt || now;
|
|
7537
|
+
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
7017
7538
|
return {
|
|
7539
|
+
...message,
|
|
7018
7540
|
role,
|
|
7019
7541
|
content,
|
|
7020
|
-
timestamp
|
|
7542
|
+
timestamp,
|
|
7543
|
+
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
7021
7544
|
};
|
|
7022
7545
|
});
|
|
7023
7546
|
}
|
|
7547
|
+
normalizeParsedMessages(parsedMessages, scope) {
|
|
7548
|
+
return this.hydrateParsedMessages(parsedMessages, scope).map((message) => ({
|
|
7549
|
+
role: message.role,
|
|
7550
|
+
content: message.content,
|
|
7551
|
+
timestamp: message.timestamp,
|
|
7552
|
+
receivedAt: message.receivedAt,
|
|
7553
|
+
kind: message.kind,
|
|
7554
|
+
id: message.id,
|
|
7555
|
+
index: message.index,
|
|
7556
|
+
meta: message.meta,
|
|
7557
|
+
senderName: message.senderName
|
|
7558
|
+
}));
|
|
7559
|
+
}
|
|
7024
7560
|
sliceFromOffset(text, start) {
|
|
7025
7561
|
if (!text) return "";
|
|
7026
7562
|
if (!Number.isFinite(start) || start <= 0) return text;
|
|
@@ -7030,14 +7566,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
7030
7566
|
buildParseInput(baseMessages, partialResponse, scope) {
|
|
7031
7567
|
const buffer = scope ? this.sliceFromOffset(this.accumulatedBuffer, scope.bufferStart) || this.accumulatedBuffer : this.accumulatedBuffer;
|
|
7032
7568
|
const rawBuffer = scope ? this.sliceFromOffset(this.accumulatedRawBuffer, scope.rawBufferStart) || this.accumulatedRawBuffer : this.accumulatedRawBuffer;
|
|
7569
|
+
const screenText = this.terminalScreen.getText();
|
|
7570
|
+
const recentBuffer = buffer.slice(-1e3) || this.recentOutputBuffer;
|
|
7033
7571
|
return {
|
|
7034
7572
|
buffer,
|
|
7035
7573
|
rawBuffer,
|
|
7036
|
-
recentBuffer
|
|
7037
|
-
screenText
|
|
7574
|
+
recentBuffer,
|
|
7575
|
+
screenText,
|
|
7576
|
+
screen: buildCliScreenSnapshot(screenText),
|
|
7577
|
+
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
7578
|
+
recentScreen: buildCliScreenSnapshot(recentBuffer),
|
|
7038
7579
|
messages: [...baseMessages],
|
|
7039
7580
|
partialResponse,
|
|
7040
|
-
promptText: scope?.prompt || ""
|
|
7581
|
+
promptText: scope?.prompt || "",
|
|
7582
|
+
settings: { ...this.runtimeSettings }
|
|
7041
7583
|
};
|
|
7042
7584
|
}
|
|
7043
7585
|
setStatus(status, trigger) {
|
|
@@ -7143,6 +7685,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
7143
7685
|
const scriptNames = Object.keys(scripts).filter((k) => typeof scripts[k] === "function");
|
|
7144
7686
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
7145
7687
|
}
|
|
7688
|
+
updateRuntimeSettings(settings) {
|
|
7689
|
+
this.runtimeSettings = { ...settings };
|
|
7690
|
+
}
|
|
7146
7691
|
// ─── Lifecycle ─────────────────────────────────
|
|
7147
7692
|
setServerConn(serverConn) {
|
|
7148
7693
|
this.serverConn = serverConn;
|
|
@@ -7277,6 +7822,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
7277
7822
|
this.spawnAt = Date.now();
|
|
7278
7823
|
this.startupParseGate = true;
|
|
7279
7824
|
this.startupBuffer = "";
|
|
7825
|
+
this.startupFirstOutputAt = 0;
|
|
7826
|
+
if (this.startupSettleTimer) {
|
|
7827
|
+
clearTimeout(this.startupSettleTimer);
|
|
7828
|
+
this.startupSettleTimer = null;
|
|
7829
|
+
}
|
|
7280
7830
|
this.terminalScreen.reset(24, 80);
|
|
7281
7831
|
this.pendingTerminalQueryTail = "";
|
|
7282
7832
|
this.currentTurnScope = null;
|
|
@@ -7290,7 +7840,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
7290
7840
|
this.recordTrace("ready", {
|
|
7291
7841
|
runtimeMeta: this.getRuntimeMetadata()
|
|
7292
7842
|
});
|
|
7293
|
-
this.setStatus("
|
|
7843
|
+
this.setStatus("starting", "pty_ready");
|
|
7844
|
+
this.scheduleStartupSettleCheck();
|
|
7294
7845
|
this.onStatusChange?.();
|
|
7295
7846
|
}
|
|
7296
7847
|
// ─── Output Handling ────────────────────────────
|
|
@@ -7305,6 +7856,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
7305
7856
|
this.lastScreenSnapshot = normalizedScreenSnapshot;
|
|
7306
7857
|
this.lastScreenChangeAt = now;
|
|
7307
7858
|
}
|
|
7859
|
+
if (this.startupParseGate && !this.startupFirstOutputAt && (cleanData.trim() || normalizedScreenSnapshot.trim())) {
|
|
7860
|
+
this.startupFirstOutputAt = now;
|
|
7861
|
+
}
|
|
7308
7862
|
if (this.idleFinishCandidate && (rawData.length > 0 || cleanData.length > 0)) {
|
|
7309
7863
|
this.clearIdleFinishCandidate("new_output");
|
|
7310
7864
|
}
|
|
@@ -7315,6 +7869,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
7315
7869
|
cleanPreview: this.summarizeTraceText(cleanData, 300),
|
|
7316
7870
|
screenText: this.summarizeTraceText(this.terminalScreen.getText(), 1200)
|
|
7317
7871
|
});
|
|
7872
|
+
if (this.startupParseGate) {
|
|
7873
|
+
this.scheduleStartupSettleCheck();
|
|
7874
|
+
}
|
|
7318
7875
|
if (this.isWaitingForResponse && cleanData) {
|
|
7319
7876
|
this.responseBuffer = (this.responseBuffer + cleanData).slice(-8e3);
|
|
7320
7877
|
}
|
|
@@ -7328,27 +7885,51 @@ var init_provider_cli_adapter = __esm({
|
|
|
7328
7885
|
this.recentOutputBuffer = (this.recentOutputBuffer + cleanData).slice(-1e3);
|
|
7329
7886
|
this.accumulatedBuffer = (this.accumulatedBuffer + cleanData).slice(-_ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
7330
7887
|
this.accumulatedRawBuffer = (this.accumulatedRawBuffer + rawData).slice(-_ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
7331
|
-
|
|
7332
|
-
this.startupBuffer += cleanData;
|
|
7333
|
-
const elapsed = Date.now() - this.spawnAt;
|
|
7334
|
-
const screenText = this.terminalScreen.getText() || "";
|
|
7335
|
-
const startupModal = this.getStartupConfirmationModal(screenText);
|
|
7336
|
-
const scriptStatus = startupModal ? "waiting_approval" : this.runDetectStatus(this.startupBuffer);
|
|
7337
|
-
const hasInteractivePrompt = this.looksLikeVisibleIdlePrompt(screenText);
|
|
7338
|
-
const startupStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
|
|
7339
|
-
const isReady = (scriptStatus === "idle" || scriptStatus === "waiting_approval") && hasInteractivePrompt && startupStableMs >= 700 || !!startupModal && startupStableMs >= 700 || elapsed > 8e3 || this.startupBuffer.length > 12e3;
|
|
7340
|
-
if (isReady) {
|
|
7341
|
-
this.startupParseGate = false;
|
|
7342
|
-
this.ready = true;
|
|
7343
|
-
LOG.info(
|
|
7344
|
-
"CLI",
|
|
7345
|
-
`[${this.cliType}] Startup ready (${elapsed}ms, scriptStatus=${scriptStatus}, prompt=${hasInteractivePrompt}, stableMs=${startupStableMs}) providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"}`
|
|
7346
|
-
);
|
|
7347
|
-
this.onStatusChange?.();
|
|
7348
|
-
}
|
|
7349
|
-
}
|
|
7888
|
+
this.resolveStartupState("output");
|
|
7350
7889
|
this.scheduleSettle();
|
|
7351
7890
|
}
|
|
7891
|
+
resolveStartupState(trigger) {
|
|
7892
|
+
if (!this.startupParseGate) return;
|
|
7893
|
+
const now = Date.now();
|
|
7894
|
+
const screenText = this.terminalScreen.getText() || "";
|
|
7895
|
+
const normalizedScreen = normalizeScreenSnapshot(screenText);
|
|
7896
|
+
const hasStartupOutput = !!this.startupFirstOutputAt || !!normalizedScreen.trim();
|
|
7897
|
+
if (!hasStartupOutput) return;
|
|
7898
|
+
const stableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
|
|
7899
|
+
if (stableMs < 2e3) return;
|
|
7900
|
+
const startupModal = this.getStartupConfirmationModal(screenText);
|
|
7901
|
+
this.startupParseGate = false;
|
|
7902
|
+
if (this.startupSettleTimer) {
|
|
7903
|
+
clearTimeout(this.startupSettleTimer);
|
|
7904
|
+
this.startupSettleTimer = null;
|
|
7905
|
+
}
|
|
7906
|
+
this.ready = true;
|
|
7907
|
+
if (startupModal) {
|
|
7908
|
+
this.activeModal = startupModal;
|
|
7909
|
+
this.setStatus("waiting_approval", `startup_ready:${trigger}`);
|
|
7910
|
+
} else {
|
|
7911
|
+
this.setStatus("idle", `startup_ready:${trigger}`);
|
|
7912
|
+
}
|
|
7913
|
+
LOG.info(
|
|
7914
|
+
"CLI",
|
|
7915
|
+
`[${this.cliType}] Startup settled (${trigger}, stableMs=${stableMs}, modal=${!!startupModal}) providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"}`
|
|
7916
|
+
);
|
|
7917
|
+
this.onStatusChange?.();
|
|
7918
|
+
}
|
|
7919
|
+
scheduleStartupSettleCheck() {
|
|
7920
|
+
if (!this.startupParseGate) return;
|
|
7921
|
+
if (this.startupSettleTimer) clearTimeout(this.startupSettleTimer);
|
|
7922
|
+
const now = Date.now();
|
|
7923
|
+
const stableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
|
|
7924
|
+
const delayMs = Math.max(250, 2050 - stableMs);
|
|
7925
|
+
this.startupSettleTimer = setTimeout(() => {
|
|
7926
|
+
this.startupSettleTimer = null;
|
|
7927
|
+
this.resolveStartupState("startup_timer");
|
|
7928
|
+
if (this.startupParseGate && Date.now() - this.spawnAt < 1e4) {
|
|
7929
|
+
this.scheduleStartupSettleCheck();
|
|
7930
|
+
}
|
|
7931
|
+
}, delayMs);
|
|
7932
|
+
}
|
|
7352
7933
|
scheduleSettle() {
|
|
7353
7934
|
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
7354
7935
|
const settleEpoch = this.responseEpoch;
|
|
@@ -7415,11 +7996,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
7415
7996
|
if (allLines.length === 0) return false;
|
|
7416
7997
|
const recentLines = allLines.slice(-12);
|
|
7417
7998
|
const promptIndex = this.findLastMatchingLineIndex(recentLines, (line) => /^[❯›>]\s*$/.test(line));
|
|
7418
|
-
const activeRegion = promptIndex >= 0 ? recentLines.slice(promptIndex
|
|
7999
|
+
const activeRegion = promptIndex >= 0 ? recentLines.slice(Math.max(0, promptIndex - 2), promptIndex) : recentLines;
|
|
7419
8000
|
if (activeRegion.length === 0) return false;
|
|
7420
8001
|
return activeRegion.some((line) => this.looksLikeClaudeGeneratingLine(line));
|
|
7421
8002
|
}
|
|
7422
8003
|
refineDetectedStatus(status, tail, screenText) {
|
|
8004
|
+
if (this.startupParseGate) {
|
|
8005
|
+
return this.getStartupConfirmationModal(screenText || "") ? "waiting_approval" : "starting";
|
|
8006
|
+
}
|
|
7423
8007
|
if (status === "waiting_approval") return status;
|
|
7424
8008
|
if (this.detectClaudeGeneratingOverride(screenText || "", tail)) return "generating";
|
|
7425
8009
|
return status;
|
|
@@ -7458,6 +8042,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
7458
8042
|
const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
|
|
7459
8043
|
return quietForMs < 1200 || screenStableMs < 1200 || !commitResult.hasAssistant;
|
|
7460
8044
|
}
|
|
8045
|
+
hasRecentInteractiveActivity(now) {
|
|
8046
|
+
const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
|
|
8047
|
+
const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : Number.MAX_SAFE_INTEGER;
|
|
8048
|
+
return quietForMs < _ProviderCliAdapter.STATUS_ACTIVITY_HOLD_MS || screenStableMs < _ProviderCliAdapter.STATUS_ACTIVITY_HOLD_MS;
|
|
8049
|
+
}
|
|
7461
8050
|
getStartupConfirmationModal(screenText) {
|
|
7462
8051
|
const text = sanitizeTerminalText(String(screenText || ""));
|
|
7463
8052
|
if (!text.trim()) return null;
|
|
@@ -7485,13 +8074,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
7485
8074
|
const startedAt = Date.now();
|
|
7486
8075
|
let loggedWait = false;
|
|
7487
8076
|
while (Date.now() - startedAt < maxWaitMs) {
|
|
8077
|
+
this.resolveStartupState("interactive_wait");
|
|
7488
8078
|
const screenText = this.terminalScreen.getText() || "";
|
|
7489
8079
|
const hasPrompt = this.looksLikeVisibleIdlePrompt(screenText);
|
|
7490
8080
|
const stableMs = this.lastScreenChangeAt ? Date.now() - this.lastScreenChangeAt : 0;
|
|
7491
8081
|
const recentlyOutput = this.lastNonEmptyOutputAt ? Date.now() - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
|
|
7492
8082
|
const status = this.runDetectStatus(this.recentOutputBuffer) || this.currentStatus;
|
|
7493
8083
|
const startupLikelyActive = /Welcome back|Tips for getting|Recent activity|Claude Code v\d/i.test(screenText);
|
|
7494
|
-
const interactiveReady = hasPrompt && stableMs >= 700 && recentlyOutput >= 350 && status !== "
|
|
8084
|
+
const interactiveReady = hasPrompt && stableMs >= 700 && recentlyOutput >= 350 && status !== "generating";
|
|
7495
8085
|
if (interactiveReady) {
|
|
7496
8086
|
if (loggedWait) {
|
|
7497
8087
|
LOG.info(
|
|
@@ -7530,6 +8120,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7530
8120
|
}
|
|
7531
8121
|
const tail = this.settledBuffer;
|
|
7532
8122
|
const screenText = this.terminalScreen.getText() || "";
|
|
8123
|
+
this.resolveStartupState("settled");
|
|
8124
|
+
if (this.startupParseGate) {
|
|
8125
|
+
return;
|
|
8126
|
+
}
|
|
7533
8127
|
const startupModal = this.getStartupConfirmationModal(screenText);
|
|
7534
8128
|
const modal = this.runParseApproval(tail) || startupModal;
|
|
7535
8129
|
const rawScriptStatus = this.runDetectStatus(tail);
|
|
@@ -7592,6 +8186,28 @@ var init_provider_cli_adapter = __esm({
|
|
|
7592
8186
|
} else {
|
|
7593
8187
|
clearPendingScriptStatus();
|
|
7594
8188
|
}
|
|
8189
|
+
const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
|
|
8190
|
+
const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity;
|
|
8191
|
+
if (shouldHoldGenerating) {
|
|
8192
|
+
this.clearIdleFinishCandidate("hold_generating_recent_activity");
|
|
8193
|
+
this.setStatus("generating", "recent_activity_hold");
|
|
8194
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
8195
|
+
this.idleTimeout = setTimeout(() => {
|
|
8196
|
+
if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
|
|
8197
|
+
this.finishResponse();
|
|
8198
|
+
}
|
|
8199
|
+
}, this.timeouts.generatingIdle);
|
|
8200
|
+
this.recordTrace("hold_generating_recent_activity", {
|
|
8201
|
+
scriptStatus,
|
|
8202
|
+
recentInteractiveActivity,
|
|
8203
|
+
lastNonEmptyOutputAt: this.lastNonEmptyOutputAt,
|
|
8204
|
+
lastScreenChangeAt: this.lastScreenChangeAt,
|
|
8205
|
+
holdMs: _ProviderCliAdapter.STATUS_ACTIVITY_HOLD_MS,
|
|
8206
|
+
...this.buildTraceParseSnapshot(this.currentTurnScope, this.responseBuffer)
|
|
8207
|
+
});
|
|
8208
|
+
this.onStatusChange?.();
|
|
8209
|
+
return;
|
|
8210
|
+
}
|
|
7595
8211
|
if (scriptStatus === "waiting_approval") {
|
|
7596
8212
|
this.clearIdleFinishCandidate("waiting_approval");
|
|
7597
8213
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
@@ -7669,8 +8285,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
7669
8285
|
const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
|
|
7670
8286
|
const hasAssistantTurn = !!lastParsedAssistant;
|
|
7671
8287
|
const assistantLength = lastParsedAssistant?.content?.length || 0;
|
|
7672
|
-
const idleQuietThresholdMs = Math.max(
|
|
7673
|
-
const idleStableThresholdMs =
|
|
8288
|
+
const idleQuietThresholdMs = Math.max(2e3, this.timeouts.outputSettle);
|
|
8289
|
+
const idleStableThresholdMs = 2e3;
|
|
7674
8290
|
const idleReady = visibleIdlePrompt && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
|
|
7675
8291
|
const candidate = this.idleFinishCandidate;
|
|
7676
8292
|
const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === this.lastOutputAt && candidate.lastScreenChangeAt === this.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= _ProviderCliAdapter.IDLE_FINISH_CONFIRM_MS;
|
|
@@ -7784,7 +8400,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7784
8400
|
this.currentTurnScope
|
|
7785
8401
|
);
|
|
7786
8402
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
7787
|
-
this.committedMessages = this.normalizeParsedMessages(parsed.messages);
|
|
8403
|
+
this.committedMessages = this.normalizeParsedMessages(parsed.messages, this.currentTurnScope);
|
|
7788
8404
|
const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
|
|
7789
8405
|
if (promptForTrim) {
|
|
7790
8406
|
const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
@@ -7825,7 +8441,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
7825
8441
|
const status = this.cliScripts.detectStatus({
|
|
7826
8442
|
tail: text.slice(-500),
|
|
7827
8443
|
screenText,
|
|
7828
|
-
rawBuffer: this.accumulatedRawBuffer
|
|
8444
|
+
rawBuffer: this.accumulatedRawBuffer,
|
|
8445
|
+
screen: buildCliScreenSnapshot(screenText),
|
|
8446
|
+
tailScreen: buildCliScreenSnapshot(text.slice(-500))
|
|
7829
8447
|
});
|
|
7830
8448
|
return this.refineDetectedStatus(status, text, screenText || "");
|
|
7831
8449
|
} catch (e) {
|
|
@@ -7836,11 +8454,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
7836
8454
|
runParseApproval(tail) {
|
|
7837
8455
|
if (!this.cliScripts?.parseApproval) return null;
|
|
7838
8456
|
try {
|
|
8457
|
+
const screenText = this.terminalScreen.getText();
|
|
8458
|
+
const buffer = screenText || this.accumulatedBuffer;
|
|
7839
8459
|
return this.cliScripts.parseApproval({
|
|
7840
|
-
buffer
|
|
7841
|
-
screenText
|
|
8460
|
+
buffer,
|
|
8461
|
+
screenText,
|
|
7842
8462
|
rawBuffer: this.accumulatedRawBuffer,
|
|
7843
|
-
tail
|
|
8463
|
+
tail,
|
|
8464
|
+
screen: buildCliScreenSnapshot(screenText),
|
|
8465
|
+
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
8466
|
+
tailScreen: buildCliScreenSnapshot(tail)
|
|
7844
8467
|
});
|
|
7845
8468
|
} catch (e) {
|
|
7846
8469
|
LOG.warn("CLI", `[${this.cliType}] parseApproval error: ${e.message}`);
|
|
@@ -7856,6 +8479,21 @@ var init_provider_cli_adapter = __esm({
|
|
|
7856
8479
|
activeModal: this.activeModal
|
|
7857
8480
|
};
|
|
7858
8481
|
}
|
|
8482
|
+
seedCommittedMessages(messages) {
|
|
8483
|
+
const normalized = (Array.isArray(messages) ? messages : []).filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message) => ({
|
|
8484
|
+
role: message.role,
|
|
8485
|
+
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
8486
|
+
timestamp: typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0,
|
|
8487
|
+
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : void 0,
|
|
8488
|
+
kind: typeof message.kind === "string" ? message.kind : void 0,
|
|
8489
|
+
id: typeof message.id === "string" ? message.id : void 0,
|
|
8490
|
+
index: typeof message.index === "number" ? message.index : void 0,
|
|
8491
|
+
meta: message.meta && typeof message.meta === "object" ? { ...message.meta } : void 0,
|
|
8492
|
+
senderName: typeof message.senderName === "string" ? message.senderName : void 0
|
|
8493
|
+
}));
|
|
8494
|
+
this.committedMessages = normalized;
|
|
8495
|
+
this.syncMessageViews();
|
|
8496
|
+
}
|
|
7859
8497
|
/**
|
|
7860
8498
|
* Script-based full parse — returns ReadChatResult.
|
|
7861
8499
|
* Called by command handler / dashboard for rich content rendering.
|
|
@@ -7866,12 +8504,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
7866
8504
|
this.responseBuffer,
|
|
7867
8505
|
this.currentTurnScope
|
|
7868
8506
|
);
|
|
8507
|
+
const shouldPreferCommittedMessages = !this.currentTurnScope && this.currentStatus === "idle" && !this.activeModal;
|
|
7869
8508
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
8509
|
+
const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => ({
|
|
8510
|
+
...message,
|
|
8511
|
+
id: message.id || `msg_${index}`,
|
|
8512
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
8513
|
+
kind: message.kind || "standard",
|
|
8514
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
8515
|
+
})) : this.hydrateParsedMessages(parsed.messages, this.currentTurnScope);
|
|
7870
8516
|
return {
|
|
7871
8517
|
id: parsed.id || "cli_session",
|
|
7872
8518
|
status: parsed.status || this.currentStatus,
|
|
7873
8519
|
title: parsed.title || this.cliName,
|
|
7874
|
-
messages:
|
|
8520
|
+
messages: hydratedMessages,
|
|
7875
8521
|
activeModal: parsed.activeModal ?? this.activeModal,
|
|
7876
8522
|
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0
|
|
7877
8523
|
};
|
|
@@ -7892,6 +8538,21 @@ var init_provider_cli_adapter = __esm({
|
|
|
7892
8538
|
activeModal: this.activeModal
|
|
7893
8539
|
};
|
|
7894
8540
|
}
|
|
8541
|
+
async invokeScript(scriptName, args) {
|
|
8542
|
+
const fn = this.cliScripts?.[scriptName];
|
|
8543
|
+
if (typeof fn !== "function") {
|
|
8544
|
+
throw new Error(`CLI script '${scriptName}' not available`);
|
|
8545
|
+
}
|
|
8546
|
+
const input = this.buildParseInput(
|
|
8547
|
+
this.committedMessages,
|
|
8548
|
+
this.responseBuffer,
|
|
8549
|
+
this.currentTurnScope
|
|
8550
|
+
);
|
|
8551
|
+
return await Promise.resolve(fn({
|
|
8552
|
+
...input,
|
|
8553
|
+
args: args && typeof args === "object" ? { ...args } : {}
|
|
8554
|
+
}));
|
|
8555
|
+
}
|
|
7895
8556
|
parseCurrentTranscript(baseMessages, partialResponse, scope) {
|
|
7896
8557
|
if (!this.cliScripts?.parseOutput) return null;
|
|
7897
8558
|
try {
|
|
@@ -7947,12 +8608,23 @@ ${data.message || ""}`.trim();
|
|
|
7947
8608
|
if (this.startupParseGate) {
|
|
7948
8609
|
const deadline = Date.now() + 1e4;
|
|
7949
8610
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
8611
|
+
this.resolveStartupState("send_wait");
|
|
7950
8612
|
await new Promise((resolve13) => setTimeout(resolve13, 50));
|
|
7951
8613
|
}
|
|
7952
8614
|
}
|
|
8615
|
+
await this.waitForInteractivePrompt();
|
|
8616
|
+
if (!this.ready) {
|
|
8617
|
+
this.resolveStartupState("send_precheck");
|
|
8618
|
+
const screenText = this.terminalScreen.getText() || "";
|
|
8619
|
+
const hasPrompt = this.looksLikeVisibleIdlePrompt(screenText);
|
|
8620
|
+
if (hasPrompt && this.currentStatus === "idle") {
|
|
8621
|
+
this.ready = true;
|
|
8622
|
+
this.startupParseGate = false;
|
|
8623
|
+
LOG.info("CLI", `[${this.cliType}] sendMessage recovered idle prompt readiness`);
|
|
8624
|
+
}
|
|
8625
|
+
}
|
|
7953
8626
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
7954
8627
|
if (this.isWaitingForResponse) return;
|
|
7955
|
-
await this.waitForInteractivePrompt();
|
|
7956
8628
|
const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
|
|
7957
8629
|
if (blockingModal || this.currentStatus === "waiting_approval") {
|
|
7958
8630
|
throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
|
|
@@ -7996,8 +8668,6 @@ ${data.message || ""}`.trim();
|
|
|
7996
8668
|
}
|
|
7997
8669
|
this.responseEpoch += 1;
|
|
7998
8670
|
this.responseSettleIgnoreUntil = Date.now() + submitDelayMs + this.timeouts.outputSettle + 250;
|
|
7999
|
-
this.setStatus("generating", "sendMessage");
|
|
8000
|
-
this.onStatusChange?.();
|
|
8001
8671
|
const startResponseTimeout = () => {
|
|
8002
8672
|
if (this.responseTimeout) clearTimeout(this.responseTimeout);
|
|
8003
8673
|
this.responseTimeout = setTimeout(() => {
|
|
@@ -8016,7 +8686,7 @@ ${data.message || ""}`.trim();
|
|
|
8016
8686
|
const retrySubmitIfStuck = (attempt) => {
|
|
8017
8687
|
this.submitRetryTimer = null;
|
|
8018
8688
|
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
8019
|
-
if (this.currentStatus
|
|
8689
|
+
if (this.currentStatus === "waiting_approval") return;
|
|
8020
8690
|
if ((this.responseBuffer || "").trim()) return;
|
|
8021
8691
|
const screenText = this.terminalScreen.getText();
|
|
8022
8692
|
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
@@ -8051,7 +8721,7 @@ ${data.message || ""}`.trim();
|
|
|
8051
8721
|
this.submitRetryTimer = setTimeout(() => {
|
|
8052
8722
|
this.submitRetryTimer = null;
|
|
8053
8723
|
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
8054
|
-
if (this.currentStatus
|
|
8724
|
+
if (this.currentStatus === "waiting_approval") return;
|
|
8055
8725
|
if ((this.responseBuffer || "").trim()) return;
|
|
8056
8726
|
const screenText = this.terminalScreen.getText();
|
|
8057
8727
|
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
@@ -8483,6 +9153,7 @@ var init_cli_provider_instance = __esm({
|
|
|
8483
9153
|
init_status_monitor();
|
|
8484
9154
|
init_chat_history();
|
|
8485
9155
|
init_logger();
|
|
9156
|
+
init_control_effects();
|
|
8486
9157
|
CachedDatabaseSync = null;
|
|
8487
9158
|
CliProviderInstance = class {
|
|
8488
9159
|
constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
|
|
@@ -8511,6 +9182,8 @@ var init_cli_provider_instance = __esm({
|
|
|
8511
9182
|
generatingDebounceTimer = null;
|
|
8512
9183
|
generatingDebouncePending = null;
|
|
8513
9184
|
lastApprovalEventAt = 0;
|
|
9185
|
+
controlValues = {};
|
|
9186
|
+
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
8514
9187
|
historyWriter;
|
|
8515
9188
|
runtimeMessages = [];
|
|
8516
9189
|
instanceId;
|
|
@@ -8523,6 +9196,7 @@ var init_cli_provider_instance = __esm({
|
|
|
8523
9196
|
async init(context) {
|
|
8524
9197
|
this.context = context;
|
|
8525
9198
|
this.settings = context.settings || {};
|
|
9199
|
+
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
8526
9200
|
this.monitor.updateConfig({
|
|
8527
9201
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
8528
9202
|
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
@@ -8538,6 +9212,21 @@ var init_cli_provider_instance = __esm({
|
|
|
8538
9212
|
this.detectStatusTransition();
|
|
8539
9213
|
});
|
|
8540
9214
|
await this.adapter.spawn();
|
|
9215
|
+
if (this.providerSessionId) {
|
|
9216
|
+
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
9217
|
+
if (restoredHistory.messages.length > 0) {
|
|
9218
|
+
this.adapter.seedCommittedMessages(
|
|
9219
|
+
restoredHistory.messages.map((message) => ({
|
|
9220
|
+
role: message.role,
|
|
9221
|
+
content: message.content,
|
|
9222
|
+
timestamp: message.receivedAt,
|
|
9223
|
+
receivedAt: message.receivedAt,
|
|
9224
|
+
kind: message.kind,
|
|
9225
|
+
senderName: message.senderName
|
|
9226
|
+
}))
|
|
9227
|
+
);
|
|
9228
|
+
}
|
|
9229
|
+
}
|
|
8541
9230
|
if (this.providerSessionId && this.launchMode === "resume") {
|
|
8542
9231
|
const resumedAt = Date.now();
|
|
8543
9232
|
this.historyWriter.appendSystemMarker(
|
|
@@ -8618,6 +9307,12 @@ var init_cli_provider_instance = __esm({
|
|
|
8618
9307
|
}
|
|
8619
9308
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
8620
9309
|
const parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
9310
|
+
const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
|
|
9311
|
+
if (controlValues) {
|
|
9312
|
+
this.controlValues = controlValues;
|
|
9313
|
+
} else if (Object.keys(this.controlValues).length > 0) {
|
|
9314
|
+
this.controlValues = {};
|
|
9315
|
+
}
|
|
8621
9316
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
8622
9317
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
8623
9318
|
if (parsedMessages.length > 0) {
|
|
@@ -8638,6 +9333,7 @@ var init_cli_provider_instance = __esm({
|
|
|
8638
9333
|
);
|
|
8639
9334
|
}
|
|
8640
9335
|
}
|
|
9336
|
+
this.applyProviderResponse(parsedStatus, { phase: "immediate" });
|
|
8641
9337
|
return {
|
|
8642
9338
|
type: this.type,
|
|
8643
9339
|
name: this.provider.name,
|
|
@@ -8667,8 +9363,7 @@ var init_cli_provider_instance = __esm({
|
|
|
8667
9363
|
attachedClients: runtime.attachedClients || []
|
|
8668
9364
|
} : void 0,
|
|
8669
9365
|
resume: this.provider.resume,
|
|
8670
|
-
controlValues:
|
|
8671
|
-
// CLI controls not yet wired from stream
|
|
9366
|
+
controlValues: this.controlValues,
|
|
8672
9367
|
providerControls: this.provider.controls
|
|
8673
9368
|
};
|
|
8674
9369
|
}
|
|
@@ -8679,6 +9374,15 @@ var init_cli_provider_instance = __esm({
|
|
|
8679
9374
|
getPresentationMode() {
|
|
8680
9375
|
return this.presentationMode;
|
|
8681
9376
|
}
|
|
9377
|
+
updateSettings(newSettings) {
|
|
9378
|
+
this.settings = { ...newSettings };
|
|
9379
|
+
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
9380
|
+
this.monitor.updateConfig({
|
|
9381
|
+
approvalAlert: this.settings.approvalAlert !== false,
|
|
9382
|
+
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
9383
|
+
longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
|
|
9384
|
+
});
|
|
9385
|
+
}
|
|
8682
9386
|
onEvent(event, data) {
|
|
8683
9387
|
if (event === "send_message" && data?.text) {
|
|
8684
9388
|
void this.adapter.sendMessage(data.text).catch((e) => {
|
|
@@ -8690,22 +9394,27 @@ var init_cli_provider_instance = __esm({
|
|
|
8690
9394
|
void this.adapter.resolveAction(data).catch((e) => {
|
|
8691
9395
|
LOG.warn("CLI", `[${this.type}] resolve_action failed: ${e?.message || e}`);
|
|
8692
9396
|
});
|
|
9397
|
+
} else if (event === "provider_state_patch" && data && typeof data === "object") {
|
|
9398
|
+
this.applyProviderResponse(data, { phase: "immediate" });
|
|
8693
9399
|
}
|
|
8694
9400
|
}
|
|
8695
9401
|
dispose() {
|
|
8696
9402
|
this.adapter.shutdown();
|
|
8697
9403
|
this.monitor.reset();
|
|
9404
|
+
this.appliedEffectKeys.clear();
|
|
8698
9405
|
}
|
|
8699
9406
|
completedDebounceTimer = null;
|
|
8700
9407
|
completedDebouncePending = null;
|
|
8701
9408
|
detectStatusTransition() {
|
|
8702
9409
|
const now = Date.now();
|
|
8703
9410
|
const adapterStatus = this.adapter.getStatus();
|
|
9411
|
+
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
8704
9412
|
const newStatus = adapterStatus.status;
|
|
8705
9413
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
8706
9414
|
const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
|
|
8707
9415
|
const partial2 = this.adapter.getPartialResponse();
|
|
8708
9416
|
const progressFingerprint = newStatus === "generating" ? `${partial2 || ""}::${adapterStatus.messages.at(-1)?.content || ""}`.slice(-2e3) : void 0;
|
|
9417
|
+
const previousStatus = this.lastStatus;
|
|
8709
9418
|
if (newStatus !== this.lastStatus) {
|
|
8710
9419
|
LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
8711
9420
|
if (this.lastStatus === "idle" && newStatus === "generating") {
|
|
@@ -8798,6 +9507,9 @@ var init_cli_provider_instance = __esm({
|
|
|
8798
9507
|
}
|
|
8799
9508
|
this.lastStatus = newStatus;
|
|
8800
9509
|
}
|
|
9510
|
+
this.applyProviderResponse(parsedStatus, {
|
|
9511
|
+
phase: newStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
|
|
9512
|
+
});
|
|
8801
9513
|
const agentKey = `${this.type}:cli`;
|
|
8802
9514
|
const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
|
|
8803
9515
|
for (const me of monitorEvents) {
|
|
@@ -8813,6 +9525,88 @@ var init_cli_provider_instance = __esm({
|
|
|
8813
9525
|
this.events = [];
|
|
8814
9526
|
return events;
|
|
8815
9527
|
}
|
|
9528
|
+
applyProviderResponse(data, options) {
|
|
9529
|
+
if (!data || typeof data !== "object") return;
|
|
9530
|
+
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
9531
|
+
if (controlValues) {
|
|
9532
|
+
this.controlValues = { ...this.controlValues, ...controlValues };
|
|
9533
|
+
}
|
|
9534
|
+
const effects = normalizeProviderEffects(data);
|
|
9535
|
+
for (const effect of effects) {
|
|
9536
|
+
const effectWhen = effect.when || "immediate";
|
|
9537
|
+
if (effectWhen === "turn_completed" && options.phase !== "turn_completed") continue;
|
|
9538
|
+
if (effectWhen === "immediate" && options.phase === "turn_completed") continue;
|
|
9539
|
+
const effectKey = this.getEffectDedupKey(effect);
|
|
9540
|
+
if (this.appliedEffectKeys.has(effectKey)) continue;
|
|
9541
|
+
this.appliedEffectKeys.add(effectKey);
|
|
9542
|
+
if (effect.persist !== false) {
|
|
9543
|
+
const persisted = this.getPersistedEffectContent(effect);
|
|
9544
|
+
if (persisted) this.appendRuntimeSystemMessage(persisted, effectKey);
|
|
9545
|
+
}
|
|
9546
|
+
if (effect.type === "message" && effect.message) {
|
|
9547
|
+
const content = typeof effect.message.content === "string" ? effect.message.content : JSON.stringify(effect.message.content);
|
|
9548
|
+
this.pushEvent({
|
|
9549
|
+
event: "provider:message",
|
|
9550
|
+
timestamp: Date.now(),
|
|
9551
|
+
content,
|
|
9552
|
+
role: effect.message.role || "system",
|
|
9553
|
+
kind: effect.message.kind,
|
|
9554
|
+
senderName: effect.message.senderName
|
|
9555
|
+
});
|
|
9556
|
+
} else if (effect.type === "toast" && effect.toast) {
|
|
9557
|
+
this.pushEvent({
|
|
9558
|
+
event: "provider:toast",
|
|
9559
|
+
effectId: effect.id || effectKey,
|
|
9560
|
+
timestamp: Date.now(),
|
|
9561
|
+
message: effect.toast.message,
|
|
9562
|
+
level: effect.toast.level || "info"
|
|
9563
|
+
});
|
|
9564
|
+
} else if (effect.type === "notification" && effect.notification) {
|
|
9565
|
+
this.pushEvent({
|
|
9566
|
+
event: "provider:notification",
|
|
9567
|
+
effectId: effect.id || effectKey,
|
|
9568
|
+
timestamp: Date.now(),
|
|
9569
|
+
title: effect.notification.title,
|
|
9570
|
+
message: effect.notification.body,
|
|
9571
|
+
content: typeof effect.notification.bubbleContent === "string" ? effect.notification.bubbleContent : effect.notification.body,
|
|
9572
|
+
level: effect.notification.level || "info",
|
|
9573
|
+
channels: effect.notification.channels || ["toast"],
|
|
9574
|
+
preferenceKey: effect.notification.preferenceKey
|
|
9575
|
+
});
|
|
9576
|
+
}
|
|
9577
|
+
}
|
|
9578
|
+
if (this.appliedEffectKeys.size > 200) {
|
|
9579
|
+
this.appliedEffectKeys = new Set(Array.from(this.appliedEffectKeys).slice(-100));
|
|
9580
|
+
}
|
|
9581
|
+
}
|
|
9582
|
+
getEffectDedupKey(effect) {
|
|
9583
|
+
if (effect.id) return `provider_effect:${effect.id}`;
|
|
9584
|
+
if (effect.type === "message") {
|
|
9585
|
+
const content = typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
|
|
9586
|
+
return `provider_effect:message:${content}`;
|
|
9587
|
+
}
|
|
9588
|
+
if (effect.type === "notification") {
|
|
9589
|
+
return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
|
|
9590
|
+
}
|
|
9591
|
+
return `provider_effect:toast:${effect.toast?.message || ""}`;
|
|
9592
|
+
}
|
|
9593
|
+
getPersistedEffectContent(effect) {
|
|
9594
|
+
if (effect.type === "message") {
|
|
9595
|
+
return typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
|
|
9596
|
+
}
|
|
9597
|
+
if (effect.type === "toast") {
|
|
9598
|
+
return effect.toast?.message || null;
|
|
9599
|
+
}
|
|
9600
|
+
if (effect.type === "notification") {
|
|
9601
|
+
if (typeof effect.notification?.bubbleContent === "string") return effect.notification.bubbleContent;
|
|
9602
|
+
if (typeof effect.notification?.title === "string" && effect.notification.title.trim()) {
|
|
9603
|
+
return `${effect.notification.title}
|
|
9604
|
+
${effect.notification.body || ""}`.trim();
|
|
9605
|
+
}
|
|
9606
|
+
return effect.notification?.body || null;
|
|
9607
|
+
}
|
|
9608
|
+
return null;
|
|
9609
|
+
}
|
|
8816
9610
|
// ─── Adapter access (backward compat) ──────────────────
|
|
8817
9611
|
getAdapter() {
|
|
8818
9612
|
return this.adapter;
|
|
@@ -29667,6 +30461,22 @@ function getMacAppIdentifiers() {
|
|
|
29667
30461
|
function getWinProcessNames() {
|
|
29668
30462
|
return getProviderLoader().getWinProcessNames();
|
|
29669
30463
|
}
|
|
30464
|
+
function getProviderMeta(ideId) {
|
|
30465
|
+
return getProviderLoader().getMeta(ideId);
|
|
30466
|
+
}
|
|
30467
|
+
function getPreferredLaunchMethod(ideId, platform11) {
|
|
30468
|
+
const prefer = getProviderMeta(ideId)?.launch?.prefer;
|
|
30469
|
+
const value = prefer?.[platform11];
|
|
30470
|
+
return value === "cli" || value === "app" || value === "auto" ? value : "auto";
|
|
30471
|
+
}
|
|
30472
|
+
function getCdpStartupTimeoutMs(ideId) {
|
|
30473
|
+
const value = getProviderMeta(ideId)?.launch?.cdpStartupTimeoutMs;
|
|
30474
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 15e3;
|
|
30475
|
+
return Math.max(1e3, Math.floor(value));
|
|
30476
|
+
}
|
|
30477
|
+
function escapeForAppleScript(value) {
|
|
30478
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
30479
|
+
}
|
|
29670
30480
|
async function findFreePort(ports) {
|
|
29671
30481
|
for (const port2 of ports) {
|
|
29672
30482
|
const free = await checkPortFree(port2);
|
|
@@ -29719,12 +30529,12 @@ async function killIdeProcess(ideId) {
|
|
|
29719
30529
|
try {
|
|
29720
30530
|
if (plat === "darwin" && appName) {
|
|
29721
30531
|
try {
|
|
29722
|
-
(0, import_child_process6.execSync)(`osascript -e 'tell application "${appName}" to quit' 2>/dev/null`, {
|
|
30532
|
+
(0, import_child_process6.execSync)(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
|
|
29723
30533
|
timeout: 5e3
|
|
29724
30534
|
});
|
|
29725
30535
|
} catch {
|
|
29726
30536
|
try {
|
|
29727
|
-
(0, import_child_process6.execSync)(`pkill -
|
|
30537
|
+
(0, import_child_process6.execSync)(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
|
|
29728
30538
|
} catch {
|
|
29729
30539
|
}
|
|
29730
30540
|
}
|
|
@@ -29754,7 +30564,7 @@ async function killIdeProcess(ideId) {
|
|
|
29754
30564
|
}
|
|
29755
30565
|
if (plat === "darwin" && appName) {
|
|
29756
30566
|
try {
|
|
29757
|
-
(0, import_child_process6.execSync)(`pkill -9 -
|
|
30567
|
+
(0, import_child_process6.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
|
|
29758
30568
|
} catch {
|
|
29759
30569
|
}
|
|
29760
30570
|
} else if (plat === "win32" && winProcesses) {
|
|
@@ -29777,8 +30587,23 @@ function isIdeRunning(ideId) {
|
|
|
29777
30587
|
if (plat === "darwin") {
|
|
29778
30588
|
const appName = getMacAppIdentifiers()[ideId];
|
|
29779
30589
|
if (!appName) return false;
|
|
29780
|
-
|
|
29781
|
-
|
|
30590
|
+
try {
|
|
30591
|
+
const result = (0, import_child_process6.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
|
|
30592
|
+
encoding: "utf-8",
|
|
30593
|
+
timeout: 3e3
|
|
30594
|
+
});
|
|
30595
|
+
return result.trim().length > 0;
|
|
30596
|
+
} catch {
|
|
30597
|
+
const result = (0, import_child_process6.execSync)(
|
|
30598
|
+
`osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
|
|
30599
|
+
{
|
|
30600
|
+
encoding: "utf-8",
|
|
30601
|
+
timeout: 3e3,
|
|
30602
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
30603
|
+
}
|
|
30604
|
+
);
|
|
30605
|
+
return Number.parseInt(result.trim() || "0", 10) > 0;
|
|
30606
|
+
}
|
|
29782
30607
|
} else if (plat === "win32") {
|
|
29783
30608
|
const winProcesses = getWinProcessNames()[ideId];
|
|
29784
30609
|
if (!winProcesses) return false;
|
|
@@ -29927,7 +30752,8 @@ async function launchWithCdp(options = {}) {
|
|
|
29927
30752
|
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
29928
30753
|
}
|
|
29929
30754
|
let cdpReady = false;
|
|
29930
|
-
|
|
30755
|
+
const waitDeadline = Date.now() + getCdpStartupTimeoutMs(targetIde.id);
|
|
30756
|
+
while (Date.now() < waitDeadline) {
|
|
29931
30757
|
await new Promise((r) => setTimeout(r, 500));
|
|
29932
30758
|
if (await isCdpActive(port)) {
|
|
29933
30759
|
cdpReady = true;
|
|
@@ -29956,14 +30782,18 @@ async function launchWithCdp(options = {}) {
|
|
|
29956
30782
|
}
|
|
29957
30783
|
async function launchMacOS(ide, port, workspace, newWindow) {
|
|
29958
30784
|
const appName = getMacAppIdentifiers()[ide.id];
|
|
30785
|
+
const preferredMethod = getPreferredLaunchMethod(ide.id, "darwin");
|
|
29959
30786
|
const args = ["--remote-debugging-port=" + port];
|
|
29960
30787
|
if (newWindow) args.push("--new-window");
|
|
29961
30788
|
if (workspace) args.push(workspace);
|
|
29962
|
-
|
|
30789
|
+
const canUseCli = !!ide.cliCommand;
|
|
30790
|
+
const canUseAppLauncher = !!appName;
|
|
30791
|
+
const useAppLauncher = preferredMethod === "app" ? canUseAppLauncher : preferredMethod === "cli" ? false : !canUseCli && canUseAppLauncher;
|
|
30792
|
+
if (!useAppLauncher && ide.cliCommand) {
|
|
30793
|
+
(0, import_child_process6.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
|
|
30794
|
+
} else if (appName) {
|
|
29963
30795
|
const openArgs = ["-a", appName, "--args", ...args];
|
|
29964
30796
|
(0, import_child_process6.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
|
|
29965
|
-
} else if (ide.cliCommand) {
|
|
29966
|
-
(0, import_child_process6.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
|
|
29967
30797
|
} else {
|
|
29968
30798
|
throw new Error(`No app identifier or CLI for ${ide.displayName}`);
|
|
29969
30799
|
}
|
|
@@ -30281,6 +31111,7 @@ function buildStatusSnapshot(options) {
|
|
|
30281
31111
|
workspaces: wsState.workspaces,
|
|
30282
31112
|
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
30283
31113
|
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
31114
|
+
terminalSizingMode: cfg.terminalSizingMode || "measured",
|
|
30284
31115
|
recentLaunches: buildRecentLaunches(recentActivity),
|
|
30285
31116
|
terminalBackend,
|
|
30286
31117
|
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
@@ -31129,6 +31960,7 @@ var ProviderStreamAdapter;
|
|
|
31129
31960
|
var init_provider_adapter = __esm({
|
|
31130
31961
|
"../../oss/packages/daemon-core/src/agent-stream/provider-adapter.ts"() {
|
|
31131
31962
|
"use strict";
|
|
31963
|
+
init_control_effects();
|
|
31132
31964
|
ProviderStreamAdapter = class {
|
|
31133
31965
|
agentType;
|
|
31134
31966
|
agentName;
|
|
@@ -31188,19 +32020,10 @@ var init_provider_adapter = __esm({
|
|
|
31188
32020
|
mode: data.mode,
|
|
31189
32021
|
activeModal: data.activeModal
|
|
31190
32022
|
};
|
|
31191
|
-
|
|
31192
|
-
|
|
31193
|
-
|
|
31194
|
-
|
|
31195
|
-
const val = data[ctrl.readFrom];
|
|
31196
|
-
if (val !== void 0 && val !== null) {
|
|
31197
|
-
cv[ctrl.id] = typeof val === "object" ? val.name || val.id || String(val) : val;
|
|
31198
|
-
}
|
|
31199
|
-
}
|
|
31200
|
-
if (data.model && !cv["model"]) cv["model"] = data.model;
|
|
31201
|
-
if (data.mode && !cv["mode"]) cv["mode"] = data.mode;
|
|
31202
|
-
if (Object.keys(cv).length > 0) state.controlValues = cv;
|
|
31203
|
-
}
|
|
32023
|
+
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
32024
|
+
if (controlValues) state.controlValues = controlValues;
|
|
32025
|
+
const effects = normalizeProviderEffects(data);
|
|
32026
|
+
if (effects.length > 0) state.effects = effects;
|
|
31204
32027
|
if (state.messages.length > 0) {
|
|
31205
32028
|
this.lastSuccessState = state;
|
|
31206
32029
|
}
|
|
@@ -31760,6 +32583,8 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
31760
32583
|
activeModal: stream.activeModal || null,
|
|
31761
32584
|
model: stream.model || void 0,
|
|
31762
32585
|
mode: stream.mode || void 0,
|
|
32586
|
+
controlValues: stream.controlValues || void 0,
|
|
32587
|
+
effects: stream.effects || void 0,
|
|
31763
32588
|
sessionId: stream.sessionId || stream.instanceId || void 0,
|
|
31764
32589
|
title: stream.title || stream.agentName || void 0,
|
|
31765
32590
|
agentType: stream.agentType || void 0,
|
|
@@ -46443,7 +47268,7 @@ var init_adhdev_daemon = __esm({
|
|
|
46443
47268
|
import_ws3 = require("ws");
|
|
46444
47269
|
import_chalk2 = __toESM(require("chalk"));
|
|
46445
47270
|
init_version();
|
|
46446
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.
|
|
47271
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.24" });
|
|
46447
47272
|
DANGEROUS_PATTERNS = [
|
|
46448
47273
|
/\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
|
|
46449
47274
|
/\bsudo\b/i,
|