@adhdev/daemon-core 0.5.31 → 0.5.33
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.d.ts +3 -0
- package/dist/index.js +56 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/agent-stream/manager.ts +5 -2
- package/src/agent-stream/provider-adapter.ts +2 -1
- package/src/cli-adapters/provider-cli-adapter.ts +13 -2
- package/src/providers/cli-provider-instance.ts +40 -10
package/package.json
CHANGED
|
@@ -47,9 +47,11 @@ export class DaemonAgentStreamManager {
|
|
|
47
47
|
if (providerLoader) {
|
|
48
48
|
const allExtProviders = providerLoader.getByCategory('extension');
|
|
49
49
|
for (const p of allExtProviders) {
|
|
50
|
-
const
|
|
50
|
+
const resolved = providerLoader.resolve(p.type);
|
|
51
|
+
if (!resolved) continue;
|
|
52
|
+
const adapter = new ProviderStreamAdapter(resolved);
|
|
51
53
|
this.allAdapters.push(adapter);
|
|
52
|
-
this.logFn(`[AgentStream] Adapter created: ${p.type} (${p.name})`);
|
|
54
|
+
this.logFn(`[AgentStream] Adapter created: ${p.type} (${p.name}) scripts=${Object.keys(resolved.scripts || {}).join(',') || 'none'}`);
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
}
|
|
@@ -147,6 +149,7 @@ export class DaemonAgentStreamManager {
|
|
|
147
149
|
const evaluate: AgentEvaluateFn = (expr, timeout) =>
|
|
148
150
|
cdp.evaluateInSessionFrame(agent.sessionId, expr, timeout);
|
|
149
151
|
const state = await agent.adapter.readChat(evaluate);
|
|
152
|
+
this.logFn(`[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${state.model || ''}${state.status === 'error' ? ' error=' + JSON.stringify((state as any).error || (state as any)._error || 'unknown') : ''}`);
|
|
150
153
|
agent.lastState = state;
|
|
151
154
|
agent.lastError = null;
|
|
152
155
|
if (state.status === 'panel_hidden') {
|
|
@@ -95,9 +95,16 @@ export interface CliProviderModule {
|
|
|
95
95
|
|
|
96
96
|
function stripAnsi(str: string): string {
|
|
97
97
|
// eslint-disable-next-line no-control-regex
|
|
98
|
-
return str
|
|
98
|
+
return str
|
|
99
|
+
// Cursor movement sequences → space (prevents word concatenation)
|
|
100
|
+
.replace(/\x1B\[\d*[A-HJKSTfG]/g, ' ')
|
|
101
|
+
// SGR and other CSI sequences → remove
|
|
102
|
+
.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, '')
|
|
103
|
+
// OSC sequences (title bar etc)
|
|
99
104
|
.replace(/\x1B\][^\x07]*\x07/g, '')
|
|
100
|
-
.replace(/\x1B\][^\x1B]*\x1B\\/g, '')
|
|
105
|
+
.replace(/\x1B\][^\x1B]*\x1B\\/g, '')
|
|
106
|
+
// Collapse multiple spaces
|
|
107
|
+
.replace(/ +/g, ' ');
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
function findBinary(name: string): string {
|
|
@@ -469,6 +476,10 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
469
476
|
}
|
|
470
477
|
|
|
471
478
|
// ─── Phase 2: Approval detect
|
|
479
|
+
// DEBUG: log recent output for approval pattern debugging
|
|
480
|
+
if (cleanData.trim().length > 5) {
|
|
481
|
+
LOG.debug('CLI', `[${this.cliType}] output chunk (${cleanData.length}): ${cleanData.slice(0, 300).replace(/\n/g, '\\n')}`);
|
|
482
|
+
}
|
|
472
483
|
const hasApproval = patterns.approval.some(p => p.test(this.recentOutputBuffer));
|
|
473
484
|
if (hasApproval && this.currentStatus !== 'waiting_approval') {
|
|
474
485
|
const inCooldown = this.lastApprovalResolvedAt && (Date.now() - this.lastApprovalResolvedAt) < this.timeouts.approvalCooldown;
|
|
@@ -28,6 +28,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
28
28
|
private monitor: StatusMonitor;
|
|
29
29
|
private generatingDebounceTimer: NodeJS.Timeout | null = null;
|
|
30
30
|
private generatingDebouncePending: { chatTitle: string; timestamp: number } | null = null;
|
|
31
|
+
private lastApprovalEventAt = 0;
|
|
31
32
|
private historyWriter: ChatHistoryWriter;
|
|
32
33
|
readonly instanceId: string;
|
|
33
34
|
|
|
@@ -149,7 +150,8 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
149
150
|
this.monitor.reset();
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
|
|
153
|
+
private completedDebounceTimer: NodeJS.Timeout | null = null;
|
|
154
|
+
private completedDebouncePending: { chatTitle: string; duration: number; timestamp: number } | null = null;
|
|
153
155
|
|
|
154
156
|
private detectStatusTransition(): void {
|
|
155
157
|
const now = Date.now();
|
|
@@ -161,7 +163,14 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
161
163
|
if (newStatus !== this.lastStatus) {
|
|
162
164
|
LOG.info('CLI', `[${this.type}] status: ${this.lastStatus} → ${newStatus}`);
|
|
163
165
|
if (this.lastStatus === 'idle' && newStatus === 'generating') {
|
|
164
|
-
|
|
166
|
+
// Cancel any pending completed event (multi-step: idle→generating resume)
|
|
167
|
+
if (this.completedDebouncePending) {
|
|
168
|
+
LOG.info('CLI', `[${this.type}] cancelled pending completed (resumed generating)`);
|
|
169
|
+
if (this.completedDebounceTimer) { clearTimeout(this.completedDebounceTimer); this.completedDebounceTimer = null; }
|
|
170
|
+
this.completedDebouncePending = null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
165
174
|
// Defer the generating_started event — if idle comes back within 1s,
|
|
166
175
|
// the whole started→completed pair was a false positive from PTY noise
|
|
167
176
|
if (this.generatingDebounceTimer) clearTimeout(this.generatingDebounceTimer);
|
|
@@ -180,14 +189,23 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
180
189
|
this.pushEvent({ event: 'agent:generating_started', ...this.generatingDebouncePending });
|
|
181
190
|
this.generatingDebouncePending = null;
|
|
182
191
|
}
|
|
192
|
+
// Cancel any pending completed
|
|
193
|
+
if (this.completedDebounceTimer) { clearTimeout(this.completedDebounceTimer); this.completedDebounceTimer = null; }
|
|
194
|
+
this.completedDebouncePending = null;
|
|
195
|
+
|
|
183
196
|
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
184
197
|
const modal = adapterStatus.activeModal;
|
|
185
198
|
LOG.info('CLI', `[${this.type}] approval modal: "${modal?.message?.slice(0, 80) ?? 'none'}"`);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
199
|
+
// Only push event if not already in waiting_approval (prevent flood from rapid cycles)
|
|
200
|
+
const approvalCooldown = 5000;
|
|
201
|
+
if (this.lastStatus !== 'waiting_approval' && (!this.lastApprovalEventAt || now - this.lastApprovalEventAt > approvalCooldown)) {
|
|
202
|
+
this.lastApprovalEventAt = now;
|
|
203
|
+
this.pushEvent({
|
|
204
|
+
event: 'agent:waiting_approval', chatTitle, timestamp: now,
|
|
205
|
+
modalMessage: modal?.message,
|
|
206
|
+
modalButtons: modal?.buttons,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
191
209
|
} else if (newStatus === 'idle' && (this.lastStatus === 'generating' || this.lastStatus === 'waiting_approval')) {
|
|
192
210
|
const duration = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1000) : 0;
|
|
193
211
|
// If debounce still pending (generating lasted < 1s), cancel both events
|
|
@@ -195,15 +213,27 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
195
213
|
LOG.info('CLI', `[${this.type}] suppressed short generating (${now - this.generatingStartedAt}ms)`);
|
|
196
214
|
if (this.generatingDebounceTimer) { clearTimeout(this.generatingDebounceTimer); this.generatingDebounceTimer = null; }
|
|
197
215
|
this.generatingDebouncePending = null;
|
|
216
|
+
this.generatingStartedAt = 0;
|
|
198
217
|
} else {
|
|
199
|
-
|
|
200
|
-
this.
|
|
218
|
+
// Debounce completed — wait 2s, if still idle then emit
|
|
219
|
+
if (this.completedDebounceTimer) clearTimeout(this.completedDebounceTimer);
|
|
220
|
+
this.completedDebouncePending = { chatTitle, duration, timestamp: now };
|
|
221
|
+
this.completedDebounceTimer = setTimeout(() => {
|
|
222
|
+
if (this.completedDebouncePending) {
|
|
223
|
+
LOG.info('CLI', `[${this.type}] completed in ${this.completedDebouncePending.duration}s`);
|
|
224
|
+
this.pushEvent({ event: 'agent:generating_completed', ...this.completedDebouncePending });
|
|
225
|
+
this.completedDebouncePending = null;
|
|
226
|
+
this.generatingStartedAt = 0;
|
|
227
|
+
}
|
|
228
|
+
this.completedDebounceTimer = null;
|
|
229
|
+
}, 2000);
|
|
201
230
|
}
|
|
202
|
-
this.generatingStartedAt = 0;
|
|
203
231
|
} else if (newStatus === 'stopped') {
|
|
204
232
|
// Cancel any pending debounce
|
|
205
233
|
if (this.generatingDebounceTimer) { clearTimeout(this.generatingDebounceTimer); this.generatingDebounceTimer = null; }
|
|
206
234
|
this.generatingDebouncePending = null;
|
|
235
|
+
if (this.completedDebounceTimer) { clearTimeout(this.completedDebounceTimer); this.completedDebounceTimer = null; }
|
|
236
|
+
this.completedDebouncePending = null;
|
|
207
237
|
this.pushEvent({ event: 'agent:stopped', chatTitle, timestamp: now });
|
|
208
238
|
}
|
|
209
239
|
this.lastStatus = newStatus;
|