@axhub/genie 0.2.11 → 0.2.12
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/api-docs.html +2 -2
- package/dist/assets/App-Clb2COtW.js +274 -0
- package/dist/assets/ImagePlaygroundPage-DqhMSbM8.js +106 -0
- package/dist/assets/ImagePlaygroundPage-MEn3NN80.css +1 -0
- package/dist/assets/ReviewApp-CDcLYe-u.js +1 -0
- package/dist/assets/{_basePickBy-BDnj7-0Z.js → _basePickBy-jUZsM51q.js} +1 -1
- package/dist/assets/{_baseUniq-Bl0JKOyl.js → _baseUniq-BXglE6_v.js} +1 -1
- package/dist/assets/{arc-DY-4Kev3.js → arc-D-oFCFBv.js} +1 -1
- package/dist/assets/{architectureDiagram-2XIMDMQ5-qw7crNVd.js → architectureDiagram-2XIMDMQ5-DC8bAnQt.js} +1 -1
- package/dist/assets/{blockDiagram-WCTKOSBZ-B9xg7ep3.js → blockDiagram-WCTKOSBZ-C4semIRc.js} +1 -1
- package/dist/assets/{c4Diagram-IC4MRINW-H9xp3ytb.js → c4Diagram-IC4MRINW-FHj1QO3y.js} +1 -1
- package/dist/assets/channel-BF4woPXX.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-B3EVDUxI.js → chunk-4BX2VUAB-D-LjsQ_s.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CGv945ef.js → chunk-55IACEB6-DI3j_d7A.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-uAT4CKWM.js → chunk-FMBD7UC4-BEVnaLFN.js} +1 -1
- package/dist/assets/{chunk-JSJVCQXG-Cbvlpkf7.js → chunk-JSJVCQXG-CSxpcErk.js} +1 -1
- package/dist/assets/{chunk-KX2RTZJC-CcqIuGat.js → chunk-KX2RTZJC-BbuhDN4h.js} +1 -1
- package/dist/assets/{chunk-NQ4KR5QH-CgrcsRuX.js → chunk-NQ4KR5QH-C3x61XQa.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-Cx0APOoV.js → chunk-QZHKN3VN-DxWOFtPh.js} +1 -1
- package/dist/assets/{chunk-WL4C6EOR-BbZirvBk.js → chunk-WL4C6EOR-Bt2OauD2.js} +1 -1
- package/dist/assets/classDiagram-VBA2DB6C-D2kHlnQ7.js +1 -0
- package/dist/assets/classDiagram-v2-RAHNMMFH-D2kHlnQ7.js +1 -0
- package/dist/assets/clone-CqBvwCJW.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-CrvmGFLD.js → cose-bilkent-S5V4N54A-Dexadrue.js} +1 -1
- package/dist/assets/{dagre-KLK3FWXG-C-W6VPjS.js → dagre-KLK3FWXG-F9U4X2xC.js} +1 -1
- package/dist/assets/{diagram-E7M64L7V-IP2q3bL0.js → diagram-E7M64L7V-B3V17aH3.js} +1 -1
- package/dist/assets/{diagram-IFDJBPK2-CQaL-XyV.js → diagram-IFDJBPK2-CdHAmLL1.js} +1 -1
- package/dist/assets/{diagram-P4PSJMXO-BxBLThfv.js → diagram-P4PSJMXO-CrTNfk8K.js} +1 -1
- package/dist/assets/{erDiagram-INFDFZHY-Dyl7bJTt.js → erDiagram-INFDFZHY-vDh9SWK9.js} +1 -1
- package/dist/assets/{flowDiagram-PKNHOUZH-B7NFMgFK.js → flowDiagram-PKNHOUZH-DpltMg7L.js} +1 -1
- package/dist/assets/{ganttDiagram-A5KZAMGK-hReWSDu2.js → ganttDiagram-A5KZAMGK-COTk2xur.js} +1 -1
- package/dist/assets/{gitGraphDiagram-K3NZZRJ6-gVgcr0ST.js → gitGraphDiagram-K3NZZRJ6-BNV7bvvj.js} +1 -1
- package/dist/assets/{graph-DNDiJhTn.js → graph-Dkeg9oys.js} +1 -1
- package/dist/assets/{highlighted-body-TPN3WLV5-DclLmTou.js → highlighted-body-TPN3WLV5-DaiQEBwR.js} +1 -1
- package/dist/assets/index-DgGmiqsP.css +1 -0
- package/dist/assets/index-DvA901Vs.js +2 -0
- package/dist/assets/{infoDiagram-LFFYTUFH-CqQOOzDA.js → infoDiagram-LFFYTUFH-CZioW3Gt.js} +1 -1
- package/dist/assets/{ishikawaDiagram-PHBUUO56-CZ0iLiHg.js → ishikawaDiagram-PHBUUO56-BbqR3i1B.js} +1 -1
- package/dist/assets/{journeyDiagram-4ABVD52K-DdfYKfNh.js → journeyDiagram-4ABVD52K-wfb-WHzl.js} +1 -1
- package/dist/assets/{kanban-definition-K7BYSVSG-C5Vf32u6.js → kanban-definition-K7BYSVSG-B3c4y3VN.js} +1 -1
- package/dist/assets/{layout-rvTEu2KS.js → layout-Xr9Z2VGF.js} +1 -1
- package/dist/assets/{linear-CD9SiYze.js → linear-JBmzAJtl.js} +1 -1
- package/dist/assets/{mermaid-O7DHMXV3-OZ8qWWwa.js → mermaid-O7DHMXV3-fDuyNLKe.js} +230 -222
- package/dist/assets/{mindmap-definition-YRQLILUH-CQxrLNVc.js → mindmap-definition-YRQLILUH-B5NTN_jD.js} +1 -1
- package/dist/assets/{pieDiagram-SKSYHLDU-XgAUByWg.js → pieDiagram-SKSYHLDU-CuO98GVu.js} +1 -1
- package/dist/assets/{quadrantDiagram-337W2JSQ-CH16ls7G.js → quadrantDiagram-337W2JSQ-LL3f4vLf.js} +1 -1
- package/dist/assets/{requirementDiagram-Z7DCOOCP-B_kQO06L.js → requirementDiagram-Z7DCOOCP-Di-2O6LH.js} +1 -1
- package/dist/assets/{sankeyDiagram-WA2Y5GQK-ofe78CyS.js → sankeyDiagram-WA2Y5GQK-9lHqrXqR.js} +1 -1
- package/dist/assets/{sequenceDiagram-2WXFIKYE-Ckbxwny6.js → sequenceDiagram-2WXFIKYE-BQu-SoGr.js} +1 -1
- package/dist/assets/{stateDiagram-RAJIS63D-DNtzCk14.js → stateDiagram-RAJIS63D-BUxvd2BC.js} +1 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-CDVexTiR.js +1 -0
- package/dist/assets/{timeline-definition-YZTLITO2-zT6CklKt.js → timeline-definition-YZTLITO2-oP47UEU6.js} +1 -1
- package/dist/assets/{treemap-KZPCXAKY-y0U2c3xG.js → treemap-KZPCXAKY-BRjDo2aE.js} +1 -1
- package/dist/assets/{vendor-codemirror-CMHSJ_9p.js → vendor-codemirror-BiCeS-y4.js} +1 -1
- package/dist/assets/{vendor-react-xmA_f8ig.js → vendor-react-DVlYPmi3.js} +1 -1
- package/dist/assets/{vennDiagram-LZ73GAT5-xKj3SjYG.js → vennDiagram-LZ73GAT5-DrRqcDqo.js} +1 -1
- package/dist/assets/{xychartDiagram-JWTSCODW-Da_qyEoX.js → xychartDiagram-JWTSCODW-DUXrymAi.js} +1 -1
- package/dist/index.html +4 -4
- package/package.json +25 -6
- package/scripts/refresh-acp-default-capabilities.mjs +160 -0
- package/server/acp-runtime/client.js +1137 -181
- package/server/acp-runtime/command-overrides.js +48 -0
- package/server/acp-runtime/index.js +576 -16
- package/server/acp-runtime/registry.js +6 -4
- package/server/acp-runtime/session-store.js +235 -92
- package/server/database/db.js +12 -3
- package/server/external-agent/ws.js +212 -11
- package/server/index.js +145 -52
- package/server/projects-watcher-config.js +4 -0
- package/server/projects.js +466 -125
- package/server/routes/cc-connect.js +5 -4
- package/server/routes/codex.js +24 -0
- package/server/routes/commands.js +144 -1
- package/server/routes/runs.js +641 -0
- package/server/routes/session-core.js +357 -109
- package/server/session-core/eventStore.js +0 -121
- package/server/session-core/providerAdapters.js +644 -163
- package/server/session-core/providerDiscovery.js +66 -38
- package/server/session-core/runRegistry.js +244 -0
- package/server/session-core/runtimeState.js +75 -3
- package/server/session-core/runtimeWriter.js +132 -10
- package/server/utils/codexImagePlayground.js +479 -0
- package/server/utils/localTerminal.js +56 -0
- package/server/utils/shellCommand.js +70 -0
- package/shared/acpCapabilities.js +393 -0
- package/shared/acpDefaultCapabilities.generated.json +141 -0
- package/shared/conversationEvents.js +425 -121
- package/dist/assets/App-VH1wNUHs.js +0 -259
- package/dist/assets/ReviewApp-D_9EN4TM.js +0 -1
- package/dist/assets/channel-CyNUnRfc.js +0 -1
- package/dist/assets/classDiagram-VBA2DB6C-DxBtyz2A.js +0 -1
- package/dist/assets/classDiagram-v2-RAHNMMFH-DxBtyz2A.js +0 -1
- package/dist/assets/clone-C341l3d0.js +0 -1
- package/dist/assets/index-DBkz_W_P.css +0 -1
- package/dist/assets/index-DdRyoXKh.js +0 -2
- package/dist/assets/stateDiagram-v2-FVOUBMTO-B3VPhiE1.js +0 -1
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { resolveWorkingDirectory } from '../utils/defaultWorkingDirectory.js';
|
|
2
2
|
import { AcpClient } from './client.js';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import {
|
|
7
|
+
buildAcpCapabilities,
|
|
8
|
+
mergeAcpCapabilitySnapshots
|
|
9
|
+
} from '../../shared/acpCapabilities.js';
|
|
3
10
|
import {
|
|
4
11
|
findAcpSessionRecord,
|
|
5
12
|
touchAcpSessionRecord
|
|
6
13
|
} from './session-store.js';
|
|
14
|
+
import { mergeAgentCommandOverrides } from './command-overrides.js';
|
|
7
15
|
|
|
8
16
|
const activeSessionClients = new Map();
|
|
17
|
+
const warmProjectClients = new Map();
|
|
9
18
|
const pendingSessionClientLoads = new Map();
|
|
10
|
-
const
|
|
19
|
+
const capabilityProbeSnapshotCache = new Map();
|
|
20
|
+
const capabilityProbeInFlight = new Map();
|
|
21
|
+
const DEFAULT_ACTIVE_SESSION_IDLE_TIMEOUT_MS = parseInt(process.env.ACP_SESSION_IDLE_TIMEOUT_MS, 10) || (15 * 60 * 1000);
|
|
22
|
+
const DEFAULT_CAPABILITY_PROBE_SETTLE_MS = parseInt(process.env.ACP_CAPABILITY_PROBE_SETTLE_MS, 10) || 120;
|
|
23
|
+
const CAPABILITY_PROBE_POLL_MS = 10;
|
|
11
24
|
|
|
12
25
|
function normalizeProvider(value) {
|
|
13
26
|
return String(value || '').trim().toLowerCase();
|
|
@@ -22,7 +35,172 @@ function createActiveSessionKey(provider, sessionId) {
|
|
|
22
35
|
return `${normalizedProvider}:${normalizedSessionId}`;
|
|
23
36
|
}
|
|
24
37
|
|
|
38
|
+
function createWarmProjectKey(provider, projectPath) {
|
|
39
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
40
|
+
const normalizedProjectPath = String(projectPath || '').trim();
|
|
41
|
+
if (!normalizedProvider || !normalizedProjectPath) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return `${normalizedProvider}:${normalizedProjectPath}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function createCapabilityProbeCacheKey(provider, projectPath) {
|
|
48
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
49
|
+
const normalizedProjectPath = String(projectPath || '').trim();
|
|
50
|
+
if (!normalizedProvider) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return `${normalizedProvider}:${normalizedProjectPath || 'global'}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function cloneJsonValue(value) {
|
|
58
|
+
if (value === undefined) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return JSON.parse(JSON.stringify(value));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function isForceRefreshOption(options = {}) {
|
|
66
|
+
return options.force === true || String(options.force || '').toLowerCase() === 'true';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readCapabilityProbeCache(provider, projectPath) {
|
|
70
|
+
const key = createCapabilityProbeCacheKey(provider, projectPath);
|
|
71
|
+
if (!key) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const cached = capabilityProbeSnapshotCache.get(key);
|
|
76
|
+
if (!cached?.snapshot) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const updatedAtMs = Date.parse(cached.snapshot.updatedAt || '');
|
|
81
|
+
const ttl = Number(cached.snapshot.ttl || 0);
|
|
82
|
+
if (!Number.isFinite(updatedAtMs) || !Number.isFinite(ttl) || ttl <= 0) {
|
|
83
|
+
capabilityProbeSnapshotCache.delete(key);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (Date.now() - updatedAtMs >= ttl) {
|
|
88
|
+
capabilityProbeSnapshotCache.delete(key);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return cloneJsonValue(cached.snapshot);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function writeCapabilityProbeCache(provider, projectPath, snapshot) {
|
|
96
|
+
const key = createCapabilityProbeCacheKey(provider, projectPath);
|
|
97
|
+
if (!key || !snapshot) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const cloned = cloneJsonValue(snapshot);
|
|
102
|
+
capabilityProbeSnapshotCache.set(key, {
|
|
103
|
+
snapshot: cloned
|
|
104
|
+
});
|
|
105
|
+
return cloneJsonValue(cloned);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function deleteCapabilityProbeCache(provider, projectPath) {
|
|
109
|
+
const key = createCapabilityProbeCacheKey(provider, projectPath);
|
|
110
|
+
if (key) {
|
|
111
|
+
capabilityProbeSnapshotCache.delete(key);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function hasConfiguredAgentCommandOverride(provider, options = {}) {
|
|
116
|
+
const overrides = mergeAgentCommandOverrides(
|
|
117
|
+
process.env.AXHUB_ACP_COMMAND_OVERRIDES,
|
|
118
|
+
options.agentCommandOverrides
|
|
119
|
+
);
|
|
120
|
+
return Boolean(overrides[normalizeProvider(provider)]);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function hasGeminiOauthCredentials() {
|
|
124
|
+
const geminiDir = path.join(os.homedir(), '.gemini');
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const content = await fs.readFile(path.join(geminiDir, 'oauth_creds.json'), 'utf8');
|
|
128
|
+
const credentials = JSON.parse(content);
|
|
129
|
+
if (credentials?.access_token || credentials?.refresh_token || credentials?.token) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const content = await fs.readFile(path.join(geminiDir, 'google_accounts.json'), 'utf8');
|
|
137
|
+
const accounts = JSON.parse(content);
|
|
138
|
+
return typeof accounts?.active === 'string' && accounts.active.trim().length > 0;
|
|
139
|
+
} catch {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function shouldSkipGeminiAutomaticAcpStartup(provider, options = {}) {
|
|
145
|
+
if (normalizeProvider(provider) !== 'gemini') {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return !hasConfiguredAgentCommandOverride(provider, options);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function shouldBlockGeminiPromptStartup(provider, options = {}) {
|
|
153
|
+
if (normalizeProvider(provider) !== 'gemini') {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (hasConfiguredAgentCommandOverride(provider, options)) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return !(await hasGeminiOauthCredentials());
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function buildSkippedGeminiCapabilityProbeSnapshot(projectPath) {
|
|
165
|
+
const snapshot = buildAcpCapabilities({
|
|
166
|
+
provider: 'gemini',
|
|
167
|
+
source: 'auth-unavailable'
|
|
168
|
+
});
|
|
169
|
+
snapshot.metadata = {
|
|
170
|
+
...(snapshot.metadata || {}),
|
|
171
|
+
probeSkipped: true,
|
|
172
|
+
authenticated: false,
|
|
173
|
+
authError: 'Skipped automatic Gemini ACP startup to avoid repeated OAuth browser launches.'
|
|
174
|
+
};
|
|
175
|
+
writeCapabilityProbeCache('gemini', projectPath, snapshot);
|
|
176
|
+
return snapshot;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function unregisterWarmProjectClient(provider, projectPath, client = null) {
|
|
180
|
+
const key = createWarmProjectKey(provider, projectPath);
|
|
181
|
+
if (!key) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const entry = warmProjectClients.get(key);
|
|
186
|
+
if (!entry) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (client && entry.client !== client) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (entry.idleTimer) {
|
|
195
|
+
clearTimeout(entry.idleTimer);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
warmProjectClients.delete(key);
|
|
199
|
+
return entry.client;
|
|
200
|
+
}
|
|
201
|
+
|
|
25
202
|
function registerActiveClient(provider, sessionId, client) {
|
|
203
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
26
204
|
const key = createActiveSessionKey(provider, sessionId);
|
|
27
205
|
if (!key) {
|
|
28
206
|
return null;
|
|
@@ -45,6 +223,7 @@ function registerActiveClient(provider, sessionId, client) {
|
|
|
45
223
|
entry.lastUsedAt = Date.now();
|
|
46
224
|
entry.idleTimer = null;
|
|
47
225
|
activeSessionClients.set(key, entry);
|
|
226
|
+
unregisterWarmProjectClient(normalizedProvider, client?.projectPath, client);
|
|
48
227
|
return entry;
|
|
49
228
|
}
|
|
50
229
|
|
|
@@ -55,6 +234,78 @@ export function resolveDefaultModel(agentKey, requestedModel) {
|
|
|
55
234
|
return normalizedRequestedModel || null;
|
|
56
235
|
}
|
|
57
236
|
|
|
237
|
+
export function createCapabilityProbeWriter(provider) {
|
|
238
|
+
let snapshot = buildAcpCapabilities({ provider, source: 'probe' });
|
|
239
|
+
let sessionId = null;
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
send(payload) {
|
|
243
|
+
if (!payload || typeof payload !== 'object') {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (typeof payload.sessionId === 'string' && payload.sessionId.trim()) {
|
|
248
|
+
sessionId = payload.sessionId.trim();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (payload.capabilitySnapshot) {
|
|
252
|
+
snapshot = mergeAcpCapabilitySnapshots(snapshot, payload.capabilitySnapshot);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (payload.type === 'session-created') {
|
|
256
|
+
snapshot = mergeAcpCapabilitySnapshots(snapshot, buildAcpCapabilities({
|
|
257
|
+
configOptions: payload.configOptions,
|
|
258
|
+
modeState: payload.modes,
|
|
259
|
+
tokenUsage: payload.tokenUsage,
|
|
260
|
+
availableCommands: payload.availableCommands,
|
|
261
|
+
provider: payload.provider || provider,
|
|
262
|
+
source: 'probe'
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (payload.type === 'conversation-event' && payload.event) {
|
|
267
|
+
const event = payload.event;
|
|
268
|
+
if (event.kind === 'mode_update') {
|
|
269
|
+
snapshot = mergeAcpCapabilitySnapshots(snapshot, buildAcpCapabilities({
|
|
270
|
+
modeState: event.payload,
|
|
271
|
+
provider: event.provider || provider,
|
|
272
|
+
source: 'probe'
|
|
273
|
+
}));
|
|
274
|
+
} else if (event.kind === 'config_option_update') {
|
|
275
|
+
snapshot = mergeAcpCapabilitySnapshots(snapshot, buildAcpCapabilities({
|
|
276
|
+
configOptions: event.payload?.configOptions,
|
|
277
|
+
provider: event.provider || provider,
|
|
278
|
+
source: 'probe'
|
|
279
|
+
}));
|
|
280
|
+
} else if (event.kind === 'usage_update') {
|
|
281
|
+
snapshot = mergeAcpCapabilitySnapshots(snapshot, buildAcpCapabilities({
|
|
282
|
+
tokenUsage: event.payload,
|
|
283
|
+
provider: event.provider || provider,
|
|
284
|
+
source: 'probe'
|
|
285
|
+
}));
|
|
286
|
+
} else if (event.kind === 'available_commands_update') {
|
|
287
|
+
snapshot = mergeAcpCapabilitySnapshots(snapshot, buildAcpCapabilities({
|
|
288
|
+
availableCommands: event.payload?.availableCommands,
|
|
289
|
+
provider: event.provider || provider,
|
|
290
|
+
source: 'probe'
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
setSessionId(nextSessionId) {
|
|
296
|
+
if (typeof nextSessionId === 'string' && nextSessionId.trim()) {
|
|
297
|
+
sessionId = nextSessionId.trim();
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
getSessionId() {
|
|
301
|
+
return sessionId;
|
|
302
|
+
},
|
|
303
|
+
getSnapshot() {
|
|
304
|
+
return snapshot;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
58
309
|
function truncateSessionSummary(text, maxLength = 50) {
|
|
59
310
|
const normalizedText = typeof text === 'string' ? text.trim() : '';
|
|
60
311
|
if (!normalizedText) {
|
|
@@ -104,6 +355,38 @@ export function deriveSessionSummaryFromPrompt(command) {
|
|
|
104
355
|
return truncateSessionSummary(extractVisibleUserPrompt(command));
|
|
105
356
|
}
|
|
106
357
|
|
|
358
|
+
function hasProbeAvailableCommands(snapshot) {
|
|
359
|
+
return Array.isArray(snapshot?.metadata?.availableCommands) && snapshot.metadata.availableCommands.length > 0;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function resolveCapabilityProbeSettleMs(options = {}) {
|
|
363
|
+
const explicit = Number(options.probeSettleMs ?? options.capabilityProbeSettleMs);
|
|
364
|
+
if (Number.isFinite(explicit) && explicit >= 0) {
|
|
365
|
+
return explicit;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return DEFAULT_CAPABILITY_PROBE_SETTLE_MS;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function delay(ms) {
|
|
372
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async function waitForCapabilityProbeSettle(writer, options = {}) {
|
|
376
|
+
const settleMs = resolveCapabilityProbeSettleMs(options);
|
|
377
|
+
if (settleMs <= 0 || hasProbeAvailableCommands(writer.getSnapshot())) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const deadline = Date.now() + settleMs;
|
|
382
|
+
while (Date.now() < deadline) {
|
|
383
|
+
await delay(Math.min(CAPABILITY_PROBE_POLL_MS, Math.max(0, deadline - Date.now())));
|
|
384
|
+
if (hasProbeAvailableCommands(writer.getSnapshot())) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
107
390
|
function unregisterActiveClient(provider, sessionId, client = null) {
|
|
108
391
|
const key = createActiveSessionKey(provider, sessionId);
|
|
109
392
|
if (!key) {
|
|
@@ -132,6 +415,26 @@ function getActiveClient(provider, sessionId) {
|
|
|
132
415
|
return key ? activeSessionClients.get(key)?.client || null : null;
|
|
133
416
|
}
|
|
134
417
|
|
|
418
|
+
function takeWarmProjectClient(provider, projectPath) {
|
|
419
|
+
const key = createWarmProjectKey(provider, projectPath);
|
|
420
|
+
if (!key) {
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const entry = warmProjectClients.get(key);
|
|
425
|
+
if (!entry) {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (entry.idleTimer) {
|
|
430
|
+
clearTimeout(entry.idleTimer);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
warmProjectClients.delete(key);
|
|
434
|
+
entry.lastUsedAt = Date.now();
|
|
435
|
+
return entry.client;
|
|
436
|
+
}
|
|
437
|
+
|
|
135
438
|
async function disposeActiveClient(provider, sessionId, client = null) {
|
|
136
439
|
const resolvedClient = unregisterActiveClient(provider, sessionId, client) || client;
|
|
137
440
|
if (resolvedClient) {
|
|
@@ -139,6 +442,22 @@ async function disposeActiveClient(provider, sessionId, client = null) {
|
|
|
139
442
|
}
|
|
140
443
|
}
|
|
141
444
|
|
|
445
|
+
export async function disposeManagedAgentClient({ provider, sessionId = null, projectPath = null, client = null } = {}) {
|
|
446
|
+
let resolvedClient = null;
|
|
447
|
+
if (sessionId) {
|
|
448
|
+
resolvedClient = unregisterActiveClient(provider, sessionId, client);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (projectPath) {
|
|
452
|
+
resolvedClient = unregisterWarmProjectClient(provider, projectPath, client) || resolvedClient;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
resolvedClient = resolvedClient || client;
|
|
456
|
+
if (resolvedClient) {
|
|
457
|
+
await resolvedClient.dispose().catch(() => {});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
142
461
|
function scheduleActiveClientCleanup(provider, sessionId, metadata = {}) {
|
|
143
462
|
if (DEFAULT_ACTIVE_SESSION_IDLE_TIMEOUT_MS <= 0) {
|
|
144
463
|
return;
|
|
@@ -177,6 +496,130 @@ function scheduleActiveClientCleanup(provider, sessionId, metadata = {}) {
|
|
|
177
496
|
entry.idleTimer.unref?.();
|
|
178
497
|
}
|
|
179
498
|
|
|
499
|
+
function scheduleWarmProjectClientCleanup(provider, projectPath) {
|
|
500
|
+
if (DEFAULT_ACTIVE_SESSION_IDLE_TIMEOUT_MS <= 0) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const key = createWarmProjectKey(provider, projectPath);
|
|
505
|
+
const entry = key ? warmProjectClients.get(key) : null;
|
|
506
|
+
if (!entry) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (entry.idleTimer) {
|
|
511
|
+
clearTimeout(entry.idleTimer);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
entry.lastUsedAt = Date.now();
|
|
515
|
+
entry.idleTimer = setTimeout(() => {
|
|
516
|
+
void (async () => {
|
|
517
|
+
const warmClient = unregisterWarmProjectClient(provider, projectPath, entry.client);
|
|
518
|
+
if (!warmClient) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
await warmClient.dispose().catch(() => {});
|
|
523
|
+
})();
|
|
524
|
+
}, DEFAULT_ACTIVE_SESSION_IDLE_TIMEOUT_MS);
|
|
525
|
+
|
|
526
|
+
entry.idleTimer.unref?.();
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export function hasReusableCapabilitySnapshot(snapshot) {
|
|
530
|
+
if (!snapshot || typeof snapshot !== 'object') {
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const capabilities = snapshot.capabilities && typeof snapshot.capabilities === 'object'
|
|
535
|
+
? snapshot.capabilities
|
|
536
|
+
: {};
|
|
537
|
+
const hasCapability = Object.values(capabilities).some(Boolean);
|
|
538
|
+
const hasCommands = Array.isArray(snapshot.metadata?.availableCommands) && snapshot.metadata.availableCommands.length > 0;
|
|
539
|
+
const hasTokenUsage = Boolean(snapshot.metadata?.tokenUsage);
|
|
540
|
+
|
|
541
|
+
return hasCapability || hasCommands || hasTokenUsage;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export function retainProjectAgentClient({ provider, projectPath, client } = {}) {
|
|
545
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
546
|
+
const key = createWarmProjectKey(normalizedProvider, projectPath);
|
|
547
|
+
if (!key || !client) {
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const existing = warmProjectClients.get(key);
|
|
552
|
+
if (existing?.idleTimer) {
|
|
553
|
+
clearTimeout(existing.idleTimer);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
warmProjectClients.set(key, {
|
|
557
|
+
client,
|
|
558
|
+
idleTimer: null,
|
|
559
|
+
lastUsedAt: Date.now()
|
|
560
|
+
});
|
|
561
|
+
scheduleWarmProjectClientCleanup(normalizedProvider, projectPath);
|
|
562
|
+
return true;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
export function retainSessionAgentClient({ provider, sessionId, client, metadata = {} } = {}) {
|
|
566
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
567
|
+
const normalizedSessionId = String(sessionId || client?.sessionId || '').trim();
|
|
568
|
+
if (!normalizedProvider || !normalizedSessionId || !client) {
|
|
569
|
+
return false;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
registerActiveClient(normalizedProvider, normalizedSessionId, client);
|
|
573
|
+
scheduleActiveClientCleanup(normalizedProvider, normalizedSessionId, {
|
|
574
|
+
projectPath: client.projectPath || metadata.projectPath || null,
|
|
575
|
+
model: client.model || metadata.model || null,
|
|
576
|
+
agentCommand: metadata.agentCommand || null
|
|
577
|
+
});
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
export async function getOrStartAgentClient({ agentKey, provider, writer, projectPath, options = {}, sessionId = null } = {}) {
|
|
582
|
+
const normalizedAgent = normalizeProvider(agentKey || provider || options.provider);
|
|
583
|
+
const normalizedSessionId = String(sessionId || options.sessionId || '').trim();
|
|
584
|
+
|
|
585
|
+
if (normalizedSessionId) {
|
|
586
|
+
const activeClient = getActiveClient(normalizedAgent, normalizedSessionId);
|
|
587
|
+
if (activeClient) {
|
|
588
|
+
registerActiveClient(normalizedAgent, normalizedSessionId, activeClient);
|
|
589
|
+
if (writer) {
|
|
590
|
+
activeClient.attachWriter(writer);
|
|
591
|
+
}
|
|
592
|
+
return {
|
|
593
|
+
client: activeClient,
|
|
594
|
+
reused: 'session'
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const warmClient = takeWarmProjectClient(normalizedAgent, projectPath);
|
|
600
|
+
if (warmClient) {
|
|
601
|
+
if (writer) {
|
|
602
|
+
warmClient.attachWriter(writer);
|
|
603
|
+
}
|
|
604
|
+
return {
|
|
605
|
+
client: warmClient,
|
|
606
|
+
reused: 'project'
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const client = createClient({
|
|
611
|
+
normalizedAgent,
|
|
612
|
+
writer,
|
|
613
|
+
projectPath,
|
|
614
|
+
options
|
|
615
|
+
});
|
|
616
|
+
await client.start();
|
|
617
|
+
return {
|
|
618
|
+
client,
|
|
619
|
+
reused: false
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
|
|
180
623
|
async function resolveProjectPath(options = {}) {
|
|
181
624
|
const explicitProjectPath = resolveWorkingDirectory({
|
|
182
625
|
cwd: options.cwd,
|
|
@@ -202,9 +645,17 @@ function createClient({ normalizedAgent, writer, projectPath, options = {} }) {
|
|
|
202
645
|
agentKey: normalizedAgent,
|
|
203
646
|
writer,
|
|
204
647
|
projectPath,
|
|
205
|
-
agentCommandOverrides:
|
|
648
|
+
agentCommandOverrides: mergeAgentCommandOverrides(
|
|
649
|
+
process.env.AXHUB_ACP_COMMAND_OVERRIDES,
|
|
650
|
+
options.agentCommandOverrides
|
|
651
|
+
),
|
|
206
652
|
model: resolveDefaultModel(normalizedAgent, options.model),
|
|
207
|
-
permissionMode: options.permissionMode || 'default'
|
|
653
|
+
permissionMode: options.permissionMode || 'default',
|
|
654
|
+
modeId: options.modeId || options.mode || null,
|
|
655
|
+
thoughtLevel: options.thoughtLevel || options.sessionConfigOptions?.thought_level || null,
|
|
656
|
+
startTimeoutMs: options.startTimeoutMs,
|
|
657
|
+
sessionTimeoutMs: options.sessionTimeoutMs,
|
|
658
|
+
promptTimeoutMs: options.promptTimeoutMs
|
|
208
659
|
});
|
|
209
660
|
}
|
|
210
661
|
|
|
@@ -222,21 +673,29 @@ async function createOrResumeClient({ normalizedAgent, options = {}, projectPath
|
|
|
222
673
|
}
|
|
223
674
|
|
|
224
675
|
const clientPromise = (async () => {
|
|
225
|
-
const client =
|
|
226
|
-
normalizedAgent,
|
|
676
|
+
const { client } = await getOrStartAgentClient({
|
|
677
|
+
agentKey: normalizedAgent,
|
|
227
678
|
writer,
|
|
228
679
|
projectPath,
|
|
229
|
-
options
|
|
680
|
+
options,
|
|
681
|
+
sessionId: requestedSessionId
|
|
230
682
|
});
|
|
231
683
|
|
|
232
684
|
try {
|
|
233
|
-
await client.start();
|
|
234
|
-
|
|
235
685
|
if (requestedSessionId) {
|
|
236
686
|
try {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
687
|
+
if (client.canResumeSession()) {
|
|
688
|
+
try {
|
|
689
|
+
await client.resumeSession(requestedSessionId);
|
|
690
|
+
} catch (error) {
|
|
691
|
+
console.warn(`[ACP:${normalizedAgent}] Unable to resume session ${requestedSessionId} with session/resume: ${error.message}`);
|
|
692
|
+
await client.loadSession(requestedSessionId);
|
|
693
|
+
}
|
|
694
|
+
} else {
|
|
695
|
+
await client.loadSession(requestedSessionId);
|
|
696
|
+
}
|
|
697
|
+
} catch (loadError) {
|
|
698
|
+
console.warn(`[ACP:${normalizedAgent}] Unable to resume session ${requestedSessionId}: ${loadError.message}`);
|
|
240
699
|
await client.createSession();
|
|
241
700
|
client.emitSystemNotice(`Unable to resume session ${requestedSessionId}; started a new session instead.`);
|
|
242
701
|
}
|
|
@@ -248,7 +707,12 @@ async function createOrResumeClient({ normalizedAgent, options = {}, projectPath
|
|
|
248
707
|
writer?.setSessionId?.(client.sessionId);
|
|
249
708
|
return client;
|
|
250
709
|
} catch (error) {
|
|
251
|
-
await
|
|
710
|
+
await disposeManagedAgentClient({
|
|
711
|
+
provider: normalizedAgent,
|
|
712
|
+
sessionId: client.sessionId || requestedSessionId || null,
|
|
713
|
+
projectPath,
|
|
714
|
+
client
|
|
715
|
+
});
|
|
252
716
|
throw error;
|
|
253
717
|
}
|
|
254
718
|
})();
|
|
@@ -273,9 +737,16 @@ export async function executeAgentPrompt({ agentKey, command, options = {}, writ
|
|
|
273
737
|
agentKey: normalizedAgent,
|
|
274
738
|
provider: normalizedAgent
|
|
275
739
|
});
|
|
740
|
+
if (await shouldBlockGeminiPromptStartup(normalizedAgent, options)) {
|
|
741
|
+
throw new Error('Gemini CLI is not authenticated. Configure a Gemini ACP command override or sign in before sending Gemini prompts.');
|
|
742
|
+
}
|
|
743
|
+
|
|
276
744
|
const resolvedModel = resolveDefaultModel(normalizedAgent, options.model);
|
|
277
745
|
const agentCommand = options.agentCommand || null;
|
|
278
746
|
const sessionSummary = deriveSessionSummaryFromPrompt(command);
|
|
747
|
+
const clientRequestId = typeof options.clientRequestId === 'string' && options.clientRequestId.trim()
|
|
748
|
+
? options.clientRequestId.trim()
|
|
749
|
+
: null;
|
|
279
750
|
let sessionRecord = null;
|
|
280
751
|
let client = null;
|
|
281
752
|
|
|
@@ -293,7 +764,9 @@ export async function executeAgentPrompt({ agentKey, command, options = {}, writ
|
|
|
293
764
|
await client.configureForTurn({
|
|
294
765
|
writer,
|
|
295
766
|
permissionMode: options.permissionMode || 'default',
|
|
296
|
-
model: resolvedModel
|
|
767
|
+
model: resolvedModel,
|
|
768
|
+
modeId: options.modeId || options.mode || null,
|
|
769
|
+
thoughtLevel: options.thoughtLevel || options.sessionConfigOptions?.thought_level || null
|
|
297
770
|
});
|
|
298
771
|
writer?.setSessionId?.(client.sessionId);
|
|
299
772
|
|
|
@@ -313,7 +786,7 @@ export async function executeAgentPrompt({ agentKey, command, options = {}, writ
|
|
|
313
786
|
return client.sendPrompt(command, {
|
|
314
787
|
images: options.images || [],
|
|
315
788
|
resourceLinks: options.resourceLinks || [],
|
|
316
|
-
clientRequestId
|
|
789
|
+
clientRequestId
|
|
317
790
|
});
|
|
318
791
|
});
|
|
319
792
|
|
|
@@ -364,6 +837,88 @@ export async function executeAgentPrompt({ agentKey, command, options = {}, writ
|
|
|
364
837
|
}
|
|
365
838
|
}
|
|
366
839
|
|
|
840
|
+
export async function probeAgentCapabilities(agentKey, options = {}) {
|
|
841
|
+
const normalizedAgent = normalizeProvider(agentKey || options.provider);
|
|
842
|
+
const projectPath = await resolveProjectPath({
|
|
843
|
+
...options,
|
|
844
|
+
agentKey: normalizedAgent,
|
|
845
|
+
provider: normalizedAgent
|
|
846
|
+
});
|
|
847
|
+
const force = isForceRefreshOption(options);
|
|
848
|
+
if (shouldSkipGeminiAutomaticAcpStartup(normalizedAgent, options)) {
|
|
849
|
+
return buildSkippedGeminiCapabilityProbeSnapshot(projectPath);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
if (!force) {
|
|
853
|
+
const cachedSnapshot = readCapabilityProbeCache(normalizedAgent, projectPath);
|
|
854
|
+
if (cachedSnapshot) {
|
|
855
|
+
if (normalizedAgent === 'gemini' && cachedSnapshot.source === 'auth-unavailable') {
|
|
856
|
+
deleteCapabilityProbeCache(normalizedAgent, projectPath);
|
|
857
|
+
} else {
|
|
858
|
+
return cachedSnapshot;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const cacheKey = createCapabilityProbeCacheKey(normalizedAgent, projectPath);
|
|
863
|
+
if (cacheKey && capabilityProbeInFlight.has(cacheKey)) {
|
|
864
|
+
return capabilityProbeInFlight.get(cacheKey);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const cacheKey = createCapabilityProbeCacheKey(normalizedAgent, projectPath);
|
|
869
|
+
const probePromise = (async () => {
|
|
870
|
+
const writer = createCapabilityProbeWriter(normalizedAgent);
|
|
871
|
+
const { client } = await getOrStartAgentClient({
|
|
872
|
+
agentKey: normalizedAgent,
|
|
873
|
+
writer,
|
|
874
|
+
projectPath,
|
|
875
|
+
options
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
try {
|
|
879
|
+
await client.createSession();
|
|
880
|
+
await waitForCapabilityProbeSettle(writer, options);
|
|
881
|
+
const snapshot = writer.getSnapshot();
|
|
882
|
+
if (hasReusableCapabilitySnapshot(snapshot)) {
|
|
883
|
+
writeCapabilityProbeCache(normalizedAgent, projectPath, snapshot);
|
|
884
|
+
retainProjectAgentClient({
|
|
885
|
+
provider: normalizedAgent,
|
|
886
|
+
projectPath,
|
|
887
|
+
client
|
|
888
|
+
});
|
|
889
|
+
} else {
|
|
890
|
+
await client.close().catch(() => {});
|
|
891
|
+
}
|
|
892
|
+
return snapshot;
|
|
893
|
+
} catch (error) {
|
|
894
|
+
await disposeManagedAgentClient({
|
|
895
|
+
provider: normalizedAgent,
|
|
896
|
+
sessionId: client.sessionId || null,
|
|
897
|
+
projectPath,
|
|
898
|
+
client
|
|
899
|
+
});
|
|
900
|
+
throw error;
|
|
901
|
+
}
|
|
902
|
+
})();
|
|
903
|
+
|
|
904
|
+
if (!force && cacheKey) {
|
|
905
|
+
capabilityProbeInFlight.set(cacheKey, probePromise);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
try {
|
|
909
|
+
return await probePromise;
|
|
910
|
+
} finally {
|
|
911
|
+
if (cacheKey) {
|
|
912
|
+
capabilityProbeInFlight.delete(cacheKey);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
export function resetCapabilityProbeCacheForTests() {
|
|
918
|
+
capabilityProbeSnapshotCache.clear();
|
|
919
|
+
capabilityProbeInFlight.clear();
|
|
920
|
+
}
|
|
921
|
+
|
|
367
922
|
export async function abortAgentSession(agentKey, sessionId) {
|
|
368
923
|
const normalizedAgent = normalizeProvider(agentKey);
|
|
369
924
|
const client = getActiveClient(normalizedAgent, sessionId);
|
|
@@ -372,7 +927,7 @@ export async function abortAgentSession(agentKey, sessionId) {
|
|
|
372
927
|
return false;
|
|
373
928
|
}
|
|
374
929
|
|
|
375
|
-
const cancelled = await client.cancel(sessionId);
|
|
930
|
+
const cancelled = await client.cancel(sessionId, { disposeOnTimeout: true });
|
|
376
931
|
if (cancelled) {
|
|
377
932
|
await touchAcpSessionRecord({
|
|
378
933
|
provider: normalizedAgent,
|
|
@@ -439,7 +994,8 @@ export async function setAgentSessionMode(agentKey, sessionId, modeId, { writer
|
|
|
439
994
|
|
|
440
995
|
export function isAgentSessionActive(agentKey, sessionId) {
|
|
441
996
|
const key = createActiveSessionKey(agentKey, sessionId);
|
|
442
|
-
|
|
997
|
+
const client = key ? activeSessionClients.get(key)?.client : null;
|
|
998
|
+
return Boolean(client?.isPromptInFlight);
|
|
443
999
|
}
|
|
444
1000
|
|
|
445
1001
|
export function getActiveAgentSessions(agentKey = null) {
|
|
@@ -460,3 +1016,7 @@ export function getActiveAgentSessions(agentKey = null) {
|
|
|
460
1016
|
export function resolveAgentPermission(requestId, decision = {}) {
|
|
461
1017
|
return AcpClient.resolvePermissionRequest(requestId, decision);
|
|
462
1018
|
}
|
|
1019
|
+
|
|
1020
|
+
export function resolveAgentElicitation(requestId, decision = {}) {
|
|
1021
|
+
return AcpClient.resolveElicitationRequest(requestId, decision);
|
|
1022
|
+
}
|