@adhdev/daemon-core 0.8.29 → 0.8.30
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/index.js +167 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +167 -29
- package/dist/index.mjs.map +1 -1
- package/dist/providers/acp-provider-instance.d.ts +1 -0
- package/dist/providers/approval-utils.d.ts +7 -0
- package/dist/providers/cli-provider-instance.d.ts +2 -0
- package/dist/providers/contracts.d.ts +2 -0
- package/dist/providers/ide-provider-instance.d.ts +1 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/poller.ts +38 -1
- package/src/providers/acp-provider-instance.ts +17 -2
- package/src/providers/approval-utils.ts +66 -0
- package/src/providers/cli-provider-instance.ts +30 -4
- package/src/providers/contracts.d.ts +1 -0
- package/src/providers/contracts.ts +3 -1
- package/src/providers/ide-provider-instance.ts +28 -23
- package/src/providers/provider-loader.ts +26 -2
|
@@ -93,6 +93,7 @@ export declare class AcpProviderInstance implements ProviderInstance {
|
|
|
93
93
|
private convertToolCallContent;
|
|
94
94
|
private detectStatusTransition;
|
|
95
95
|
private pushEvent;
|
|
96
|
+
private appendSystemMessage;
|
|
96
97
|
private flushEvents;
|
|
97
98
|
get cliType(): string;
|
|
98
99
|
get cliName(): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProviderModule } from './contracts.js';
|
|
2
|
+
export declare function getApprovalPositiveHints(provider?: Pick<ProviderModule, 'approvalPositiveHints'> | null): string[];
|
|
3
|
+
export declare function pickApprovalButton(buttons: string[] | null | undefined, provider?: Pick<ProviderModule, 'approvalPositiveHints'> | null): {
|
|
4
|
+
index: number;
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function formatAutoApprovalMessage(modalMessage?: string, buttonLabel?: string): string;
|
|
@@ -71,6 +71,8 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
71
71
|
getAdapter(): ProviderCliAdapter;
|
|
72
72
|
get cliType(): string;
|
|
73
73
|
get cliName(): string;
|
|
74
|
+
private shouldAutoApprove;
|
|
75
|
+
private recordAutoApproval;
|
|
74
76
|
recordApprovalSelection(buttonText: string): void;
|
|
75
77
|
private formatMarkerTimestamp;
|
|
76
78
|
private maybeAppendRuntimeRecoveryMessage;
|
|
@@ -313,6 +313,8 @@ export interface ProviderModule {
|
|
|
313
313
|
resume?: ProviderResumeCapability;
|
|
314
314
|
/** Session ID probe config — auto-discovers provider session ID from local SQLite DB */
|
|
315
315
|
sessionProbe?: ProviderSessionProbe;
|
|
316
|
+
/** Approval button priority hints used when auto-approve must pick a positive action */
|
|
317
|
+
approvalPositiveHints?: string[];
|
|
316
318
|
scripts?: ProviderScripts;
|
|
317
319
|
vscodeCommands?: {
|
|
318
320
|
focusPanel?: string;
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ import type { SessionRegistry } from '../sessions/registry.js';
|
|
|
19
19
|
import { reconcileIdeRuntimeSessions } from '../sessions/reconcile.js';
|
|
20
20
|
import { LOG } from '../logging/logger.js';
|
|
21
21
|
import type { AgentStreamState } from './types.js';
|
|
22
|
+
import { formatAutoApprovalMessage, pickApprovalButton } from '../providers/approval-utils.js';
|
|
22
23
|
|
|
23
24
|
// ─── Types ───
|
|
24
25
|
|
|
@@ -189,7 +190,43 @@ export class AgentStreamPoller {
|
|
|
189
190
|
|
|
190
191
|
try {
|
|
191
192
|
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
192
|
-
|
|
193
|
+
let stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
194
|
+
if (stream?.status === 'waiting_approval') {
|
|
195
|
+
const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
|
|
196
|
+
if (autoApprove && resolvedActiveSessionId) {
|
|
197
|
+
const provider = providerLoader.getMeta(stream.agentType);
|
|
198
|
+
const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
|
|
199
|
+
const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, 'approve', buttonLabel);
|
|
200
|
+
if (approved) {
|
|
201
|
+
const effectId = [
|
|
202
|
+
'auto_approval',
|
|
203
|
+
resolvedActiveSessionId,
|
|
204
|
+
String(stream.messages?.length || 0),
|
|
205
|
+
buttonLabel,
|
|
206
|
+
String(stream.activeModal?.message || '').trim(),
|
|
207
|
+
].join(':');
|
|
208
|
+
stream = {
|
|
209
|
+
...stream,
|
|
210
|
+
status: 'streaming',
|
|
211
|
+
activeModal: undefined,
|
|
212
|
+
effects: [
|
|
213
|
+
...(stream.effects || []),
|
|
214
|
+
{
|
|
215
|
+
type: 'message',
|
|
216
|
+
id: effectId,
|
|
217
|
+
persist: true,
|
|
218
|
+
message: {
|
|
219
|
+
role: 'system',
|
|
220
|
+
senderName: 'System',
|
|
221
|
+
kind: 'system',
|
|
222
|
+
content: formatAutoApprovalMessage(stream.activeModal?.message, buttonLabel),
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
193
230
|
this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
|
|
194
231
|
} catch { }
|
|
195
232
|
}
|
|
@@ -600,8 +600,10 @@ export class AcpProviderInstance implements ProviderInstance {
|
|
|
600
600
|
}
|
|
601
601
|
|
|
602
602
|
// ─── Auto-approve: skip user confirmation ───
|
|
603
|
-
if (this.settings.autoApprove) {
|
|
604
|
-
|
|
603
|
+
if (this.settings.autoApprove !== false) {
|
|
604
|
+
const toolTitle = tc.title || tc.toolCallId || 'tool call';
|
|
605
|
+
this.log.info(`[${this.type}] Auto-approving: ${toolTitle}`);
|
|
606
|
+
this.appendSystemMessage(`Auto-approved: ${toolTitle}`);
|
|
605
607
|
const allowOption = params.options.find(o => o.kind === 'allow_once') || params.options.find(o => o.kind === 'allow_always');
|
|
606
608
|
if (allowOption) {
|
|
607
609
|
return { outcome: { outcome: 'selected', optionId: allowOption.optionId } };
|
|
@@ -1143,6 +1145,19 @@ export class AcpProviderInstance implements ProviderInstance {
|
|
|
1143
1145
|
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
1144
1146
|
}
|
|
1145
1147
|
|
|
1148
|
+
private appendSystemMessage(content: string, timestamp = Date.now()): void {
|
|
1149
|
+
const normalizedContent = String(content || '').trim();
|
|
1150
|
+
if (!normalizedContent) return;
|
|
1151
|
+
this.messages.push({
|
|
1152
|
+
role: 'system',
|
|
1153
|
+
content: normalizedContent,
|
|
1154
|
+
timestamp,
|
|
1155
|
+
});
|
|
1156
|
+
if (this.messages.length > 200) {
|
|
1157
|
+
this.messages = this.messages.slice(-100);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1146
1161
|
private flushEvents(): ProviderEvent[] {
|
|
1147
1162
|
const events = [...this.events];
|
|
1148
1163
|
this.events = [];
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ProviderModule } from './contracts.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
4
|
+
'run',
|
|
5
|
+
'approve',
|
|
6
|
+
'accept',
|
|
7
|
+
'allow once',
|
|
8
|
+
'always allow',
|
|
9
|
+
'allow',
|
|
10
|
+
'yes',
|
|
11
|
+
'proceed',
|
|
12
|
+
'continue',
|
|
13
|
+
'confirm',
|
|
14
|
+
'save',
|
|
15
|
+
'ok',
|
|
16
|
+
'trust',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
function normalizeApprovalLabel(value: string): string {
|
|
20
|
+
return String(value || '')
|
|
21
|
+
.toLowerCase()
|
|
22
|
+
.replace(/[^\p{L}\p{N}]+/gu, ' ')
|
|
23
|
+
.trim();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getApprovalPositiveHints(provider?: Pick<ProviderModule, 'approvalPositiveHints'> | null): string[] {
|
|
27
|
+
const customHints = Array.isArray(provider?.approvalPositiveHints)
|
|
28
|
+
? provider.approvalPositiveHints
|
|
29
|
+
.map((hint) => normalizeApprovalLabel(String(hint || '')))
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
: [];
|
|
32
|
+
return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function pickApprovalButton(
|
|
36
|
+
buttons: string[] | null | undefined,
|
|
37
|
+
provider?: Pick<ProviderModule, 'approvalPositiveHints'> | null,
|
|
38
|
+
): { index: number; label: string } {
|
|
39
|
+
const labels = (buttons || []).map((button) => String(button || '').trim()).filter(Boolean);
|
|
40
|
+
if (labels.length === 0) {
|
|
41
|
+
return { index: 0, label: 'Approve' };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
45
|
+
const hints = getApprovalPositiveHints(provider);
|
|
46
|
+
|
|
47
|
+
for (const hint of hints) {
|
|
48
|
+
const exactIndex = normalizedButtons.findIndex((label) => label === hint);
|
|
49
|
+
if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
|
|
50
|
+
|
|
51
|
+
const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
|
|
52
|
+
if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
|
|
53
|
+
|
|
54
|
+
const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
|
|
55
|
+
if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { index: 0, label: labels[0] };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function formatAutoApprovalMessage(modalMessage?: string, buttonLabel?: string): string {
|
|
62
|
+
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ''}`];
|
|
63
|
+
const cleanMessage = String(modalMessage || '').trim();
|
|
64
|
+
if (cleanMessage) lines.push(cleanMessage);
|
|
65
|
+
return lines.join('\n');
|
|
66
|
+
}
|
|
@@ -20,6 +20,7 @@ import { ChatHistoryWriter, readChatHistory } from '../config/chat-history.js';
|
|
|
20
20
|
import { LOG } from '../logging/logger.js';
|
|
21
21
|
import type { ChatMessage } from '../types.js';
|
|
22
22
|
import { extractProviderControlValues, normalizeProviderEffects } from './control-effects.js';
|
|
23
|
+
import { formatAutoApprovalMessage, pickApprovalButton } from './approval-utils.js';
|
|
23
24
|
|
|
24
25
|
let CachedDatabaseSync: (new (path: string, options?: { readOnly?: boolean }) => {
|
|
25
26
|
prepare(sql: string): { get(...params: Array<string | number>): unknown };
|
|
@@ -249,6 +250,8 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
249
250
|
getState(): ProviderState {
|
|
250
251
|
const adapterStatus = this.adapter.getStatus();
|
|
251
252
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
253
|
+
const autoApproveActive = adapterStatus.status === 'waiting_approval' && this.shouldAutoApprove();
|
|
254
|
+
const visibleStatus = autoApproveActive ? 'generating' : adapterStatus.status;
|
|
252
255
|
const parsedProviderSessionId = typeof parsedStatus?.providerSessionId === 'string'
|
|
253
256
|
? parsedStatus.providerSessionId.trim()
|
|
254
257
|
: '';
|
|
@@ -297,14 +300,16 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
297
300
|
type: this.type,
|
|
298
301
|
name: this.provider.name,
|
|
299
302
|
category: 'cli',
|
|
300
|
-
status:
|
|
303
|
+
status: visibleStatus,
|
|
301
304
|
mode: this.presentationMode,
|
|
302
305
|
activeChat: {
|
|
303
306
|
id: `${this.type}_${this.workingDir}`,
|
|
304
307
|
title: parsedStatus?.title || dirName,
|
|
305
|
-
status: parsedStatus?.status
|
|
308
|
+
status: autoApproveActive && parsedStatus?.status === 'waiting_approval'
|
|
309
|
+
? 'generating'
|
|
310
|
+
: (parsedStatus?.status || visibleStatus),
|
|
306
311
|
messages: mergedMessages,
|
|
307
|
-
activeModal: parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
312
|
+
activeModal: autoApproveActive ? null : (parsedStatus?.activeModal ?? adapterStatus.activeModal),
|
|
308
313
|
inputContent: '',
|
|
309
314
|
},
|
|
310
315
|
workspace: this.workingDir,
|
|
@@ -375,7 +380,16 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
375
380
|
const now = Date.now();
|
|
376
381
|
const adapterStatus = this.adapter.getStatus();
|
|
377
382
|
const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
|
|
378
|
-
const
|
|
383
|
+
const rawStatus = adapterStatus.status;
|
|
384
|
+
const autoApproveActive = rawStatus === 'waiting_approval' && this.shouldAutoApprove();
|
|
385
|
+
if (autoApproveActive) {
|
|
386
|
+
const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(adapterStatus.activeModal?.buttons, this.provider);
|
|
387
|
+
this.recordAutoApproval(adapterStatus.activeModal?.message, buttonLabel, now);
|
|
388
|
+
setTimeout(() => {
|
|
389
|
+
this.adapter.resolveModal(buttonIndex);
|
|
390
|
+
}, 0);
|
|
391
|
+
}
|
|
392
|
+
const newStatus = autoApproveActive ? 'generating' : rawStatus;
|
|
379
393
|
const dirName = this.workingDir.split('/').filter(Boolean).pop() || 'session';
|
|
380
394
|
const chatTitle = `${this.provider.name} · ${dirName}`;
|
|
381
395
|
const partial = this.adapter.getPartialResponse();
|
|
@@ -603,6 +617,18 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
603
617
|
get cliType(): string { return this.type; }
|
|
604
618
|
get cliName(): string { return this.provider.name; }
|
|
605
619
|
|
|
620
|
+
private shouldAutoApprove(): boolean {
|
|
621
|
+
return this.settings.autoApprove !== false;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
private recordAutoApproval(modalMessage?: string, buttonLabel?: string, now = Date.now()): void {
|
|
625
|
+
this.appendRuntimeSystemMessage(
|
|
626
|
+
formatAutoApprovalMessage(modalMessage, buttonLabel),
|
|
627
|
+
`auto_approval:${now}:${buttonLabel || 'approve'}`,
|
|
628
|
+
now,
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
|
|
606
632
|
recordApprovalSelection(buttonText: string): void {
|
|
607
633
|
const cleanButton = String(buttonText || '').trim();
|
|
608
634
|
if (!cleanButton) return;
|
|
@@ -253,6 +253,7 @@ export interface ProviderModule {
|
|
|
253
253
|
};
|
|
254
254
|
cleanOutput?: (raw: string, lastUserInput?: string) => string;
|
|
255
255
|
resume?: ProviderResumeCapability;
|
|
256
|
+
approvalPositiveHints?: string[];
|
|
256
257
|
scripts?: ProviderScripts;
|
|
257
258
|
vscodeCommands?: {
|
|
258
259
|
focusPanel?: string;
|
|
@@ -388,8 +388,10 @@ export interface ProviderModule {
|
|
|
388
388
|
};
|
|
389
389
|
cleanOutput?: (raw: string, lastUserInput?: string) => string;
|
|
390
390
|
resume?: ProviderResumeCapability;
|
|
391
|
-
|
|
391
|
+
/** Session ID probe config — auto-discovers provider session ID from local SQLite DB */
|
|
392
392
|
sessionProbe?: ProviderSessionProbe;
|
|
393
|
+
/** Approval button priority hints used when auto-approve must pick a positive action */
|
|
394
|
+
approvalPositiveHints?: string[];
|
|
393
395
|
|
|
394
396
|
// ─── CDP scripts (ide/extension category) ───
|
|
395
397
|
scripts?: ProviderScripts;
|
|
@@ -19,6 +19,7 @@ import { ChatHistoryWriter } from '../config/chat-history.js';
|
|
|
19
19
|
import { LOG } from '../logging/logger.js';
|
|
20
20
|
import { extractProviderControlValues, normalizeProviderEffects } from './control-effects.js';
|
|
21
21
|
import type { ChatMessage } from '../types.js';
|
|
22
|
+
import { formatAutoApprovalMessage, pickApprovalButton } from './approval-utils.js';
|
|
22
23
|
|
|
23
24
|
export class IdeProviderInstance implements ProviderInstance {
|
|
24
25
|
readonly type: string;
|
|
@@ -103,6 +104,11 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
103
104
|
|
|
104
105
|
getState(): ProviderState {
|
|
105
106
|
const cdp = this.context?.cdp;
|
|
107
|
+
const autoApproveActive = (
|
|
108
|
+
this.currentStatus === 'waiting_approval'
|
|
109
|
+
|| this.cachedChat?.status === 'waiting_approval'
|
|
110
|
+
) && this.canAutoApprove();
|
|
111
|
+
const visibleStatus = (autoApproveActive ? 'generating' : this.currentStatus) as ProviderState['status'];
|
|
106
112
|
|
|
107
113
|
// Collect extension status
|
|
108
114
|
const extensionStates: ProviderState[] = [];
|
|
@@ -114,13 +120,15 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
114
120
|
type: this.type,
|
|
115
121
|
name: this.provider.name,
|
|
116
122
|
category: 'ide',
|
|
117
|
-
status:
|
|
123
|
+
status: visibleStatus,
|
|
118
124
|
activeChat: this.cachedChat ? {
|
|
119
125
|
id: this.cachedChat.id || 'active_session',
|
|
120
126
|
title: this.cachedChat.title || this.type,
|
|
121
|
-
status: this.cachedChat.status
|
|
127
|
+
status: autoApproveActive && this.cachedChat.status === 'waiting_approval'
|
|
128
|
+
? 'generating'
|
|
129
|
+
: (this.cachedChat.status || visibleStatus),
|
|
122
130
|
messages: this.mergeConversationMessages(this.cachedChat.messages || []),
|
|
123
|
-
activeModal: this.cachedChat.activeModal || null,
|
|
131
|
+
activeModal: autoApproveActive ? null : (this.cachedChat.activeModal || null),
|
|
124
132
|
inputContent: this.cachedChat.inputContent || '',
|
|
125
133
|
} : null,
|
|
126
134
|
workspace: this.workspace || null,
|
|
@@ -370,9 +378,11 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
370
378
|
if (!chatStatus) return;
|
|
371
379
|
|
|
372
380
|
const agentKey = `${this.type}:native`;
|
|
373
|
-
const
|
|
381
|
+
const rawAgentStatus = (chatStatus === 'streaming' || chatStatus === 'generating') ? 'generating'
|
|
374
382
|
: chatStatus === 'waiting_approval' ? 'waiting_approval'
|
|
375
383
|
: 'idle';
|
|
384
|
+
const autoApproveActive = rawAgentStatus === 'waiting_approval' && this.canAutoApprove();
|
|
385
|
+
const agentStatus = autoApproveActive ? 'generating' : rawAgentStatus;
|
|
376
386
|
const lastMsg = Array.isArray(chatData?.messages) && chatData.messages.length > 0
|
|
377
387
|
? chatData.messages[chatData.messages.length - 1]
|
|
378
388
|
: null;
|
|
@@ -414,7 +424,7 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
414
424
|
});
|
|
415
425
|
|
|
416
426
|
// Auto-approve: when waiting_approval + settings.autoApprove → auto-click approve via CDP
|
|
417
|
-
if (
|
|
427
|
+
if (rawAgentStatus === 'waiting_approval' && autoApproveActive && !this.autoApproveBusy) {
|
|
418
428
|
this.autoApproveViaScript(chatData);
|
|
419
429
|
}
|
|
420
430
|
|
|
@@ -590,6 +600,12 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
590
600
|
if (this.context) this.context.cdp = cdp;
|
|
591
601
|
}
|
|
592
602
|
|
|
603
|
+
private canAutoApprove(): boolean {
|
|
604
|
+
return this.settings.autoApprove !== false
|
|
605
|
+
&& typeof this.provider.scripts?.resolveAction === 'function'
|
|
606
|
+
&& !!this.context?.cdp?.isConnected;
|
|
607
|
+
}
|
|
608
|
+
|
|
593
609
|
// ─── Auto-approve via CDP script ────────────────────
|
|
594
610
|
|
|
595
611
|
private async autoApproveViaScript(_chatData: any): Promise<void> {
|
|
@@ -605,20 +621,16 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
605
621
|
|
|
606
622
|
this.autoApproveBusy = true;
|
|
607
623
|
try {
|
|
608
|
-
|
|
609
|
-
const buttons = _chatData?.activeModal?.buttons || [];
|
|
610
|
-
|
|
611
|
-
// Prefer buttons like 'Run', 'Approve', 'Yes'
|
|
612
|
-
for (const b of buttons) {
|
|
613
|
-
const lower = String(b).toLowerCase().replace(/[^\w]/g, '');
|
|
614
|
-
if (/^(run|approve|accept|yes|allow|always|proceed|save)/.test(lower)) {
|
|
615
|
-
targetButton = b;
|
|
616
|
-
break;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
624
|
+
const { label: targetButton } = pickApprovalButton(_chatData?.activeModal?.buttons, this.provider);
|
|
619
625
|
|
|
620
626
|
const script = scriptFn({ action: 'approve', button: targetButton, buttonText: targetButton });
|
|
621
627
|
if (!script) return;
|
|
628
|
+
const now = Date.now();
|
|
629
|
+
this.appendRuntimeSystemMessage(
|
|
630
|
+
formatAutoApprovalMessage(_chatData?.activeModal?.message, targetButton),
|
|
631
|
+
`auto_approval:${now}:${targetButton}`,
|
|
632
|
+
now,
|
|
633
|
+
);
|
|
622
634
|
|
|
623
635
|
LOG.info('IdeInstance', `[IdeInstance:${this.type}] autoApprove: executing resolveAction for "${targetButton}"`);
|
|
624
636
|
let rawResult = await cdp.evaluate(script, 10000);
|
|
@@ -641,13 +653,6 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
641
653
|
LOG.warn('IdeInstance', `[IdeInstance:${this.type}] autoApprove: cdp.send() not available for coordinate click`);
|
|
642
654
|
}
|
|
643
655
|
}
|
|
644
|
-
|
|
645
|
-
this.pushEvent({
|
|
646
|
-
event: 'agent:auto_approved',
|
|
647
|
-
chatTitle: _chatData?.title || this.provider.name,
|
|
648
|
-
timestamp: Date.now(),
|
|
649
|
-
ideType: this.type,
|
|
650
|
-
});
|
|
651
656
|
} catch (e: any) {
|
|
652
657
|
LOG.warn('IdeInstance', `[IdeInstance:${this.type}] autoApprove error: ${e?.message}`);
|
|
653
658
|
} finally {
|
|
@@ -994,7 +994,11 @@ export class ProviderLoader {
|
|
|
994
994
|
*/
|
|
995
995
|
getSettingValue(type: string, key: string): any {
|
|
996
996
|
const schemaDef = this.getSettingsSchema(type)[key];
|
|
997
|
-
const defaultVal = schemaDef
|
|
997
|
+
const defaultVal = schemaDef
|
|
998
|
+
? (key === 'autoApprove' && (schemaDef as any).type === 'boolean'
|
|
999
|
+
? true
|
|
1000
|
+
: (schemaDef as any).default)
|
|
1001
|
+
: undefined;
|
|
998
1002
|
|
|
999
1003
|
// Load user-saved value
|
|
1000
1004
|
try {
|
|
@@ -1064,15 +1068,35 @@ export class ProviderLoader {
|
|
|
1064
1068
|
private getSettingsSchema(type: string): Record<string, ProviderSettingDef> {
|
|
1065
1069
|
const provider = this.providers.get(type);
|
|
1066
1070
|
if (!provider) return {};
|
|
1067
|
-
|
|
1071
|
+
const result = {
|
|
1068
1072
|
...this.getSyntheticSettings(type, provider),
|
|
1069
1073
|
...(provider.settings || {}),
|
|
1070
1074
|
};
|
|
1075
|
+
if (result.autoApprove?.type === 'boolean') {
|
|
1076
|
+
result.autoApprove = {
|
|
1077
|
+
...result.autoApprove,
|
|
1078
|
+
default: true,
|
|
1079
|
+
public: true,
|
|
1080
|
+
label: result.autoApprove.label || 'Auto Approve',
|
|
1081
|
+
description: result.autoApprove.description || 'Automatically approve actionable prompts without sending approval alerts.',
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
return result;
|
|
1071
1085
|
}
|
|
1072
1086
|
|
|
1073
1087
|
private getSyntheticSettings(type: string, provider: ProviderModule): Record<string, ProviderSettingDef> {
|
|
1074
1088
|
const result: Record<string, ProviderSettingDef> = {};
|
|
1075
1089
|
|
|
1090
|
+
if (!provider.settings?.autoApprove) {
|
|
1091
|
+
result.autoApprove = {
|
|
1092
|
+
type: 'boolean',
|
|
1093
|
+
default: true,
|
|
1094
|
+
public: true,
|
|
1095
|
+
label: 'Auto Approve',
|
|
1096
|
+
description: 'Automatically approve actionable prompts without sending approval alerts.',
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1076
1100
|
if ((provider.category === 'cli' || provider.category === 'acp') && provider.spawn?.command && !provider.settings?.executablePath) {
|
|
1077
1101
|
result.executablePath = {
|
|
1078
1102
|
type: 'string',
|