@borgee/agents-host 0.2.44 → 0.2.56
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/README.md +23 -27
- package/dist/agents-host.d.ts +26 -5
- package/dist/agents-host.js +163 -192
- package/dist/chat/chat-control-plane.d.ts +3 -0
- package/dist/chat/sdk-chat-control-plane.d.ts +4 -3
- package/dist/chat/sdk-chat-control-plane.js +3 -0
- package/dist/cli.js +1 -5
- package/dist/compatibility-gates.d.ts +4 -0
- package/dist/compatibility-gates.js +18 -1
- package/dist/context/claude-file-brief.d.ts +2 -0
- package/dist/context/claude-file-brief.js +83 -0
- package/dist/context/compaction.d.ts +20 -0
- package/dist/context/compaction.js +59 -0
- package/dist/context/injection.d.ts +39 -6
- package/dist/context/injection.js +317 -26
- package/dist/context/main-session-delegation.d.ts +1 -1
- package/dist/context/projection-strategy.d.ts +24 -0
- package/dist/context/projection-strategy.js +90 -0
- package/dist/context/prompt.d.ts +16 -1
- package/dist/context/prompt.js +456 -22
- package/dist/context/resolved-workspace.d.ts +2 -0
- package/dist/context/resolved-workspace.js +64 -0
- package/dist/context/skill-manual.d.ts +1 -0
- package/dist/context/skill-manual.js +4 -1
- package/dist/context/turn-preparation.d.ts +8 -2
- package/dist/context/turn-preparation.js +56 -14
- package/dist/gateway/localhost-gateway.js +2 -0
- package/dist/managed-daemon.js +122 -9
- package/dist/plugin-sdk.js +276 -359
- package/dist/plugin-sdk.js.map +4 -4
- package/dist/progress-to-activity.d.ts +16 -0
- package/dist/progress-to-activity.js +24 -0
- package/dist/projection-strategy-values.d.ts +4 -0
- package/dist/projection-strategy-values.js +28 -0
- package/dist/providers/acp-progress-collector.d.ts +44 -0
- package/dist/providers/acp-progress-collector.js +130 -0
- package/dist/providers/awaiting-user.d.ts +2 -3
- package/dist/providers/awaiting-user.js +5 -7
- package/dist/providers/claude/activity-metadata.d.ts +14 -0
- package/dist/providers/claude/activity-metadata.js +81 -0
- package/dist/providers/claude/cli-client.d.ts +1 -2
- package/dist/providers/claude/cli-client.js +190 -117
- package/dist/providers/codex/cli-client.js +3 -83
- package/dist/providers/codex/project-doc.js +12 -11
- package/dist/providers/copilot/cli-client.js +3 -83
- package/dist/providers/create-provider.d.ts +2 -0
- package/dist/providers/create-provider.js +20 -4
- package/dist/state-paths.d.ts +1 -1
- package/dist/state-paths.js +3 -3
- package/dist/task-thread-resolution.d.ts +3 -2
- package/dist/types.d.ts +130 -6
- package/package.json +2 -2
- package/skills/borgee-agent/SKILL.md +9 -1
- package/skills/borgee-agent/references/task-properties.md +5 -2
- package/dist/durable-cursor-store.d.ts +0 -5
- package/dist/durable-cursor-store.js +0 -7
package/dist/agents-host.js
CHANGED
|
@@ -3,20 +3,20 @@ import { chmod, link, mkdir, readFile, readdir, rename, unlink, writeFile } from
|
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { SdkChatControlPlane } from './chat/sdk-chat-control-plane.js';
|
|
5
5
|
import { HostLogger, summarizeError } from './debug.js';
|
|
6
|
-
import {
|
|
6
|
+
import { toReportedActivity } from './progress-to-activity.js';
|
|
7
7
|
import { ATTENTION_FOLLOW_SEMANTICS_COMPATIBILITY_GATE, COLLABORATION_CAPABILITIES_DIAGNOSTICS_COMPATIBILITY_GATE, COLLABORATION_OUTCOME_MODEL_COMPATIBILITY_GATE, COLLABORATION_SKILL_FIRST_COMPATIBILITY_GATE, CONTEXT_INJECTION_COMPATIBILITY_GATE, LOCALHOST_GATEWAY_COMPATIBILITY_GATE, POLICY_AUDIT_ENFORCEMENT_COMPATIBILITY_GATE, resolveInternalPolicyMode, resolveInternalCompatibilityGates, SKILL_RUNTIME_COMPATIBILITY_GATE, TASK_THREAD_COLLABORATION_CONTRACT_COMPATIBILITY_GATE, TOKEN_BINDING_COMPATIBILITY_GATE, } from './compatibility-gates.js';
|
|
8
8
|
import { buildNormalizedAttentionSnapshot, parsePersistedAttentionSnapshot, } from './context/attention.js';
|
|
9
|
+
import { mergeCompactionSnapshot, parsePersistedCompactionSnapshot, } from './context/compaction.js';
|
|
9
10
|
import { projectTaskThreadCollaborationContract } from './context/task-thread-collaboration.js';
|
|
10
11
|
import { createLocalhostGatewayController, LOCALHOST_GATEWAY_COLLABORATION_TARGET_COOLDOWN_MS, } from './gateway/localhost-gateway.js';
|
|
11
12
|
import { extractTaskIdFromTaskAssignmentContent, resolveChannelContextPayloadPath, } from './context/injection.js';
|
|
12
13
|
import { AuthorizationAuditSink, } from './policy/authorization-audit.js';
|
|
13
14
|
import { createProvider } from './providers/create-provider.js';
|
|
14
|
-
import { resolveAttentionStatePath, resolveSharedProtocolKickoffDecisionPath, resolveSharedProtocolStatusPath, } from './state-paths.js';
|
|
15
|
+
import { resolveAttentionStatePath, resolveCompactionStatePath, resolveSharedProtocolKickoffDecisionPath, resolveSharedProtocolStatusPath, } from './state-paths.js';
|
|
15
16
|
import { appendVisibleMention as appendVisibleBodyMention, extractVisibleMentionIds as extractCanonicalMentionIds, } from './visible-mentions.js';
|
|
16
17
|
import { waitForTaskForThread } from './task-thread-resolution.js';
|
|
17
18
|
import { buildHostedIncomingContentText, buildHostedTurnContentParts, extractHostedMessageAttachments, normalizeHostedMessageAttachment, } from './hosted-turn-content.js';
|
|
18
19
|
const PRIVATE_STATE_ROOT_MODE = 0o700;
|
|
19
|
-
const STREAM_PROGRESS_EDIT_THROTTLE_MS = 150;
|
|
20
20
|
const PROTOCOL_STATE_DIRNAME = 'protocol-state';
|
|
21
21
|
const PROTOCOL_PROVIDER_TURN_TIMEOUT_MS = 120_000;
|
|
22
22
|
const PROTOCOL_KICKOFF_DECISION_TIMEOUT_MS = PROTOCOL_PROVIDER_TURN_TIMEOUT_MS;
|
|
@@ -104,9 +104,6 @@ class DefaultHostRuntime {
|
|
|
104
104
|
this.controlPlane =
|
|
105
105
|
deps.borgee ??
|
|
106
106
|
new SdkChatControlPlane(config.borgeeBaseUrl, config.agent.agentApiKey, undefined, {
|
|
107
|
-
cursorStore: createDurableCursorStore({
|
|
108
|
-
stateRootDir: config.stateRootDir,
|
|
109
|
-
}),
|
|
110
107
|
pluginId: `agents-host:${config.agent.provider}`,
|
|
111
108
|
});
|
|
112
109
|
this.gateway = createLocalhostGatewayController({
|
|
@@ -142,6 +139,7 @@ class DefaultHostRuntime {
|
|
|
142
139
|
}, deps.logger, {
|
|
143
140
|
compatibilityGates,
|
|
144
141
|
authorizationAuditSink: this.authorizationAuditSink,
|
|
142
|
+
controlPlane: this.controlPlane,
|
|
145
143
|
localhostGateway: localhostGatewayGateEnabled ? this.gateway.contextPublisher : undefined,
|
|
146
144
|
});
|
|
147
145
|
this.ensureStateRoot = deps.ensureStateRoot ?? ensurePrivateStateRoot;
|
|
@@ -258,113 +256,6 @@ function resolvePublicReplyText(reply) {
|
|
|
258
256
|
}
|
|
259
257
|
return reply.awaitingUser?.question ?? '';
|
|
260
258
|
}
|
|
261
|
-
function providerUsesDraftProgress(provider) {
|
|
262
|
-
return provider === 'claude' || provider === 'codex' || provider === 'copilot';
|
|
263
|
-
}
|
|
264
|
-
class DraftMessageController {
|
|
265
|
-
borgee;
|
|
266
|
-
channelId;
|
|
267
|
-
canWrite;
|
|
268
|
-
logger;
|
|
269
|
-
creationMetadata;
|
|
270
|
-
messageId = null;
|
|
271
|
-
currentBody = '';
|
|
272
|
-
pendingBody = null;
|
|
273
|
-
timer = null;
|
|
274
|
-
sealed = false;
|
|
275
|
-
writeChain = Promise.resolve();
|
|
276
|
-
constructor(borgee, channelId, canWrite, logger, creationMetadata) {
|
|
277
|
-
this.borgee = borgee;
|
|
278
|
-
this.channelId = channelId;
|
|
279
|
-
this.canWrite = canWrite;
|
|
280
|
-
this.logger = logger;
|
|
281
|
-
this.creationMetadata = creationMetadata;
|
|
282
|
-
}
|
|
283
|
-
update(text) {
|
|
284
|
-
if (this.sealed || !hasVisibleText(text)) {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
this.pendingBody = text;
|
|
288
|
-
if (this.timer) {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
this.timer = setTimeout(() => {
|
|
292
|
-
this.timer = null;
|
|
293
|
-
void this.flushPending().catch((error) => {
|
|
294
|
-
this.logger.error('failed to flush draft progress', error);
|
|
295
|
-
});
|
|
296
|
-
}, STREAM_PROGRESS_EDIT_THROTTLE_MS);
|
|
297
|
-
}
|
|
298
|
-
cancelProgress() {
|
|
299
|
-
if (this.timer) {
|
|
300
|
-
clearTimeout(this.timer);
|
|
301
|
-
this.timer = null;
|
|
302
|
-
}
|
|
303
|
-
this.sealed = true;
|
|
304
|
-
}
|
|
305
|
-
async finalize(finalText) {
|
|
306
|
-
this.sealed = true;
|
|
307
|
-
if (this.timer) {
|
|
308
|
-
clearTimeout(this.timer);
|
|
309
|
-
this.timer = null;
|
|
310
|
-
}
|
|
311
|
-
if (hasVisibleText(finalText)) {
|
|
312
|
-
this.pendingBody = finalText;
|
|
313
|
-
await this.flushPending();
|
|
314
|
-
return this.messageId;
|
|
315
|
-
}
|
|
316
|
-
await this.enqueueWrite(async () => {
|
|
317
|
-
if (!this.canWrite() || !this.messageId) {
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
await this.borgee.deleteMessage(this.messageId);
|
|
321
|
-
this.messageId = null;
|
|
322
|
-
this.currentBody = '';
|
|
323
|
-
this.pendingBody = null;
|
|
324
|
-
});
|
|
325
|
-
return null;
|
|
326
|
-
}
|
|
327
|
-
async discard() {
|
|
328
|
-
this.sealed = true;
|
|
329
|
-
if (this.timer) {
|
|
330
|
-
clearTimeout(this.timer);
|
|
331
|
-
this.timer = null;
|
|
332
|
-
}
|
|
333
|
-
this.pendingBody = null;
|
|
334
|
-
await this.enqueueWrite(async () => {
|
|
335
|
-
if (!this.messageId) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
await this.borgee.deleteMessage(this.messageId);
|
|
339
|
-
this.messageId = null;
|
|
340
|
-
this.currentBody = '';
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
async flushPending() {
|
|
344
|
-
await this.enqueueWrite(async () => {
|
|
345
|
-
const body = this.pendingBody;
|
|
346
|
-
if (!this.canWrite() || !body || body === this.currentBody) {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
if (this.messageId) {
|
|
350
|
-
await this.borgee.editMessage(this.messageId, body);
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
const posted = await this.borgee.postMessage({
|
|
354
|
-
channelId: this.channelId,
|
|
355
|
-
body,
|
|
356
|
-
replyToId: this.creationMetadata?.replyToId,
|
|
357
|
-
});
|
|
358
|
-
this.messageId = posted.messageId;
|
|
359
|
-
}
|
|
360
|
-
this.currentBody = body;
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
enqueueWrite(operation) {
|
|
364
|
-
this.writeChain = this.writeChain.then(operation, operation);
|
|
365
|
-
return this.writeChain;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
259
|
/**
|
|
369
260
|
* The registered task property agents-host writes to record which provider
|
|
370
261
|
* session worked a task. It matches the server's registry key.
|
|
@@ -398,9 +289,12 @@ export class AgentsHost {
|
|
|
398
289
|
*/
|
|
399
290
|
recordedAgentSessionByTask = new Map();
|
|
400
291
|
attentionSnapshotByChannel = new Map();
|
|
292
|
+
compactionSnapshotByChannel = new Map();
|
|
293
|
+
activeCompactionByChannel = new Map();
|
|
294
|
+
compactionSnapshotLoadedChannels = new Set();
|
|
295
|
+
compactionSnapshotWriteQueueByChannel = new Map();
|
|
401
296
|
missedCollaborationDiagnosticByChannel = new Map();
|
|
402
|
-
|
|
403
|
-
progressDrafts = new Map();
|
|
297
|
+
channelTurnQueues = new Map();
|
|
404
298
|
collaborationDrafts = new Map();
|
|
405
299
|
collaborationChannels = new Map();
|
|
406
300
|
participantDirectoryByUserId = new Map();
|
|
@@ -508,20 +402,32 @@ export class AgentsHost {
|
|
|
508
402
|
this.invalidateChannelTurn(channelId);
|
|
509
403
|
this.clearProtocolFallback(this.collaborationChannels.get(channelId));
|
|
510
404
|
}
|
|
511
|
-
for (const draft of this.progressDrafts.values()) {
|
|
512
|
-
draft.cancelProgress();
|
|
513
|
-
}
|
|
514
405
|
for (const channelId of [...this.collaborationDrafts.keys()]) {
|
|
515
406
|
this.clearCollaborationDraft(channelId);
|
|
516
407
|
}
|
|
517
408
|
this.awaitingUserByChannel.clear();
|
|
518
409
|
this.collaborationOutcomeByChannel.clear();
|
|
519
410
|
this.attentionSnapshotByChannel.clear();
|
|
411
|
+
this.compactionSnapshotByChannel.clear();
|
|
412
|
+
this.activeCompactionByChannel.clear();
|
|
413
|
+
this.compactionSnapshotLoadedChannels.clear();
|
|
520
414
|
this.missedCollaborationDiagnosticByChannel.clear();
|
|
521
415
|
this.recordedAgentSessionByTask.clear();
|
|
522
416
|
this.controlPlaneClosed = true;
|
|
523
|
-
|
|
417
|
+
const pendingCompactionSnapshotWrites = [...this.compactionSnapshotWriteQueueByChannel.values()];
|
|
418
|
+
let runtimeStopError;
|
|
419
|
+
try {
|
|
420
|
+
await this.runtime.stop();
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
runtimeStopError = error;
|
|
424
|
+
}
|
|
524
425
|
await Promise.allSettled([...this.activeTurns]);
|
|
426
|
+
await Promise.allSettled(pendingCompactionSnapshotWrites);
|
|
427
|
+
this.compactionSnapshotWriteQueueByChannel.clear();
|
|
428
|
+
if (runtimeStopError) {
|
|
429
|
+
throw runtimeStopError;
|
|
430
|
+
}
|
|
525
431
|
}
|
|
526
432
|
trackActiveTurn(task) {
|
|
527
433
|
this.activeTurns.add(task);
|
|
@@ -532,9 +438,7 @@ export class AgentsHost {
|
|
|
532
438
|
dispatchMessage(message) {
|
|
533
439
|
const task = this.collaborationEnabled
|
|
534
440
|
? this.handleCollaborationMessage(message)
|
|
535
|
-
:
|
|
536
|
-
? this.enqueueProgressChannelTurn(message.channel_id, () => this.handleLegacyMessage(message))
|
|
537
|
-
: this.handleLegacyMessage(message);
|
|
441
|
+
: this.enqueueChannelTurn(message.channel_id, () => this.handleLegacyMessage(message));
|
|
538
442
|
this.trackActiveTurn(task);
|
|
539
443
|
}
|
|
540
444
|
async handleLegacyMessage(msg) {
|
|
@@ -1791,12 +1695,92 @@ export class AgentsHost {
|
|
|
1791
1695
|
resolveAttentionStatePath(channelId) {
|
|
1792
1696
|
return resolveAttentionStatePath(this.config.stateRootDir, channelId);
|
|
1793
1697
|
}
|
|
1698
|
+
resolveCompactionStatePath(channelId) {
|
|
1699
|
+
return resolveCompactionStatePath(this.config.stateRootDir, channelId);
|
|
1700
|
+
}
|
|
1794
1701
|
buildDefaultAttentionSnapshot(options) {
|
|
1795
1702
|
return buildNormalizedAttentionSnapshot({
|
|
1796
1703
|
observedAt: options?.observedAt,
|
|
1797
1704
|
turnExecutionId: options?.turnExecutionId,
|
|
1798
1705
|
});
|
|
1799
1706
|
}
|
|
1707
|
+
async ensureCompactionSnapshotLoaded(channelId) {
|
|
1708
|
+
if (this.compactionSnapshotLoadedChannels.has(channelId)) {
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1711
|
+
this.compactionSnapshotLoadedChannels.add(channelId);
|
|
1712
|
+
try {
|
|
1713
|
+
const content = await readFile(this.resolveCompactionStatePath(channelId), 'utf8');
|
|
1714
|
+
const snapshot = parsePersistedCompactionSnapshot(JSON.parse(content));
|
|
1715
|
+
if (snapshot) {
|
|
1716
|
+
this.compactionSnapshotByChannel.set(channelId, snapshot);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
catch (error) {
|
|
1720
|
+
const code = error.code;
|
|
1721
|
+
if (code !== 'ENOENT') {
|
|
1722
|
+
this.logger.error('failed to load compaction state', {
|
|
1723
|
+
channelId,
|
|
1724
|
+
error: summarizeError(error),
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
this.compactionSnapshotByChannel.delete(channelId);
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
async commitCompactionSnapshot(channelId, snapshot) {
|
|
1731
|
+
if (snapshot.stage === 'started') {
|
|
1732
|
+
return;
|
|
1733
|
+
}
|
|
1734
|
+
await writePrivateJsonFile(this.resolveCompactionStatePath(channelId), snapshot);
|
|
1735
|
+
}
|
|
1736
|
+
enqueueCompactionSnapshotCommit(channelId, snapshot) {
|
|
1737
|
+
const previous = this.compactionSnapshotWriteQueueByChannel.get(channelId) ?? Promise.resolve();
|
|
1738
|
+
const next = previous
|
|
1739
|
+
.catch(() => { })
|
|
1740
|
+
.then(() => this.commitCompactionSnapshot(channelId, snapshot));
|
|
1741
|
+
this.compactionSnapshotWriteQueueByChannel.set(channelId, next);
|
|
1742
|
+
void next.catch((error) => {
|
|
1743
|
+
this.logger.error('failed to persist compaction state', {
|
|
1744
|
+
channelId,
|
|
1745
|
+
error: summarizeError(error),
|
|
1746
|
+
});
|
|
1747
|
+
}).finally(() => {
|
|
1748
|
+
if (this.compactionSnapshotWriteQueueByChannel.get(channelId) === next) {
|
|
1749
|
+
this.compactionSnapshotWriteQueueByChannel.delete(channelId);
|
|
1750
|
+
}
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
noteCompactionProgress(channelId, update, options) {
|
|
1754
|
+
const baseline = update.stage === 'started'
|
|
1755
|
+
? undefined
|
|
1756
|
+
: this.activeCompactionByChannel.get(channelId)
|
|
1757
|
+
?? this.compactionSnapshotByChannel.get(channelId);
|
|
1758
|
+
const nextSnapshot = mergeCompactionSnapshot(baseline, {
|
|
1759
|
+
provider: update.provider,
|
|
1760
|
+
stage: update.stage,
|
|
1761
|
+
observedAt: Date.now(),
|
|
1762
|
+
turnExecutionId: options?.turnExecutionId,
|
|
1763
|
+
usedTokens: update.usedTokens,
|
|
1764
|
+
contextWindowTokens: update.contextWindowTokens,
|
|
1765
|
+
failureReason: update.failureReason,
|
|
1766
|
+
});
|
|
1767
|
+
this.logger.debug('provider compaction update', {
|
|
1768
|
+
channelId,
|
|
1769
|
+
provider: nextSnapshot.provider,
|
|
1770
|
+
stage: nextSnapshot.stage,
|
|
1771
|
+
usedTokens: nextSnapshot.usedTokens,
|
|
1772
|
+
contextWindowTokens: nextSnapshot.contextWindowTokens,
|
|
1773
|
+
failureReason: nextSnapshot.failureReason,
|
|
1774
|
+
turnExecutionId: nextSnapshot.turnExecutionId,
|
|
1775
|
+
});
|
|
1776
|
+
if (nextSnapshot.stage === 'started') {
|
|
1777
|
+
this.activeCompactionByChannel.set(channelId, nextSnapshot);
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
this.activeCompactionByChannel.delete(channelId);
|
|
1781
|
+
this.compactionSnapshotByChannel.set(channelId, nextSnapshot);
|
|
1782
|
+
this.enqueueCompactionSnapshotCommit(channelId, nextSnapshot);
|
|
1783
|
+
}
|
|
1800
1784
|
/**
|
|
1801
1785
|
* Record which provider session worked this task, as agent.session_id.
|
|
1802
1786
|
*
|
|
@@ -2052,14 +2036,15 @@ export class AgentsHost {
|
|
|
2052
2036
|
taskThreadContextActive: taskThreadContext.state === 'active',
|
|
2053
2037
|
});
|
|
2054
2038
|
}
|
|
2055
|
-
resolveCollaborationCapabilityDeclarationForTurn() {
|
|
2039
|
+
resolveCollaborationCapabilityDeclarationForTurn(taskThreadContext) {
|
|
2056
2040
|
if (!this.collaborationCapabilitiesDiagnosticsEnabled) {
|
|
2057
2041
|
return undefined;
|
|
2058
2042
|
}
|
|
2059
2043
|
return {
|
|
2060
2044
|
...(this.collaborationOutcomeModelEnabled ? { collaborationOutcome: true } : {}),
|
|
2061
2045
|
...(this.attentionFollowSemanticsEnabled ? { attentionSnapshot: true } : {}),
|
|
2062
|
-
...(this.
|
|
2046
|
+
...(this.contextInjectionEnabled ? { compactionSnapshot: true } : {}),
|
|
2047
|
+
...(this.taskThreadCollaborationContractEnabled && taskThreadContext.state === 'active'
|
|
2063
2048
|
? { taskThreadCollaborationContract: true }
|
|
2064
2049
|
: {}),
|
|
2065
2050
|
missedCollaborationDiagnostic: true,
|
|
@@ -2156,18 +2141,12 @@ export class AgentsHost {
|
|
|
2156
2141
|
const turnExecutionId = activeTurn?.turnExecutionId ?? null;
|
|
2157
2142
|
const stopTyping = silentTurn ? () => { } : this.borgee.startTyping(channelId);
|
|
2158
2143
|
const collaborationGrounding = await this.buildCollaborationGrounding(authorId, options?.incomingAuthorKind, activeTurn, options?.kickoff);
|
|
2159
|
-
const
|
|
2160
|
-
!deferDelivery &&
|
|
2161
|
-
!this.collaborationEnabled &&
|
|
2162
|
-
options?.incomingAuthorKind !== 'agent' &&
|
|
2163
|
-
providerUsesDraftProgress(this.config.agent.provider) &&
|
|
2164
|
-
activeTurn?.protocol === undefined;
|
|
2165
|
-
const usePrivateCollaborationDraftProgress = !silentTurn &&
|
|
2144
|
+
const publishesCollaborationDraft = !silentTurn &&
|
|
2166
2145
|
!deferDelivery &&
|
|
2167
2146
|
this.collaborationEnabled &&
|
|
2168
2147
|
turnExecutionId != null &&
|
|
2169
|
-
providerUsesDraftProgress(this.config.agent.provider) &&
|
|
2170
2148
|
activeTurn?.protocol === undefined;
|
|
2149
|
+
const observeProviderProgress = publishesCollaborationDraft || this.config.agent.provider === 'claude';
|
|
2171
2150
|
const turnContext = {
|
|
2172
2151
|
eventType: msg.type,
|
|
2173
2152
|
channelId,
|
|
@@ -2188,12 +2167,15 @@ export class AgentsHost {
|
|
|
2188
2167
|
? this.collaborationOutcomeByChannel.get(channelId)
|
|
2189
2168
|
: undefined;
|
|
2190
2169
|
const missedCollaborationDiagnostic = this.resolveMissedCollaborationDiagnosticForTurn(channelId);
|
|
2191
|
-
const collaborationCapabilities = this.resolveCollaborationCapabilityDeclarationForTurn();
|
|
2170
|
+
const collaborationCapabilities = this.resolveCollaborationCapabilityDeclarationForTurn(taskThreadContext);
|
|
2192
2171
|
const incomingParts = options?.incomingParts
|
|
2193
2172
|
?? buildHostedTurnContentParts({
|
|
2194
2173
|
text: String(msg.content ?? msg.body ?? content),
|
|
2195
2174
|
attachments: msg.attachments,
|
|
2196
2175
|
});
|
|
2176
|
+
const activityReporter = this.beginTurnActivity(channelId, activeTurn?.generation);
|
|
2177
|
+
await this.ensureCompactionSnapshotLoaded(channelId);
|
|
2178
|
+
const compactionSnapshot = this.compactionSnapshotByChannel.get(channelId);
|
|
2197
2179
|
try {
|
|
2198
2180
|
reply = await this.provider.generateReply({
|
|
2199
2181
|
agentName: this.config.agent.agentName,
|
|
@@ -2216,17 +2198,30 @@ export class AgentsHost {
|
|
|
2216
2198
|
: undefined,
|
|
2217
2199
|
collaborationOutcome,
|
|
2218
2200
|
attentionSnapshot,
|
|
2201
|
+
compactionSnapshot,
|
|
2219
2202
|
...(taskThreadCollaborationContract ? { taskThreadCollaborationContract } : {}),
|
|
2220
2203
|
...(collaborationCapabilities ? { collaborationCapabilities } : {}),
|
|
2221
2204
|
...(missedCollaborationDiagnostic ? { missedCollaborationDiagnostic } : {}),
|
|
2222
|
-
},
|
|
2205
|
+
}, observeProviderProgress
|
|
2223
2206
|
? {
|
|
2224
2207
|
onProgress: (update) => {
|
|
2225
2208
|
if (!this.canAcceptTurnOutput(channelId, activeTurn?.generation)) {
|
|
2226
2209
|
return;
|
|
2227
2210
|
}
|
|
2228
|
-
if (
|
|
2229
|
-
this.
|
|
2211
|
+
if (update.type === 'compaction') {
|
|
2212
|
+
this.noteCompactionProgress(channelId, update.compaction, {
|
|
2213
|
+
turnExecutionId: activeTurn?.turnExecutionId ?? undefined,
|
|
2214
|
+
});
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
const reportedActivity = toReportedActivity(update);
|
|
2218
|
+
if (reportedActivity) {
|
|
2219
|
+
activityReporter.progress(reportedActivity);
|
|
2220
|
+
}
|
|
2221
|
+
if (update.type !== 'text' || update.stream !== 'answer') {
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
if (!publishesCollaborationDraft) {
|
|
2230
2225
|
return;
|
|
2231
2226
|
}
|
|
2232
2227
|
this.publishCollaborationDraft(channelId, activeTurn, update.text);
|
|
@@ -2249,7 +2244,6 @@ export class AgentsHost {
|
|
|
2249
2244
|
turnExecutionId: activeTurn?.turnExecutionId ?? undefined,
|
|
2250
2245
|
});
|
|
2251
2246
|
if (!(await this.canAcceptCompletedTurnOutput(channelId, activeTurn))) {
|
|
2252
|
-
await this.discardDraft(channelId);
|
|
2253
2247
|
if (activeTurn?.turnExecutionId) {
|
|
2254
2248
|
this.clearCollaborationDraft(channelId, {
|
|
2255
2249
|
generation: activeTurn.generation,
|
|
@@ -2298,35 +2292,7 @@ export class AgentsHost {
|
|
|
2298
2292
|
completed: true,
|
|
2299
2293
|
};
|
|
2300
2294
|
}
|
|
2301
|
-
if (
|
|
2302
|
-
const draft = this.progressDrafts.get(channelId);
|
|
2303
|
-
if (!this.started) {
|
|
2304
|
-
await draft?.discard().catch(() => { });
|
|
2305
|
-
this.progressDrafts.delete(channelId);
|
|
2306
|
-
return { reply, stale: true, completed: false };
|
|
2307
|
-
}
|
|
2308
|
-
const deliveredMessageId = await (draft ?? this.ensureProgressDraft(channelId, activeTurn?.generation, activeTurn?.delivery)).finalize(publicReplyText);
|
|
2309
|
-
this.progressDrafts.delete(channelId);
|
|
2310
|
-
this.logger.debug('completed turn', {
|
|
2311
|
-
...turnContext,
|
|
2312
|
-
durationMs: Date.now() - turnStartedAt,
|
|
2313
|
-
replyLength: publicReplyText.length,
|
|
2314
|
-
controlKind: reply?.control?.kind ?? null,
|
|
2315
|
-
controlMalformed: reply?.controlMalformed ?? false,
|
|
2316
|
-
delivery: 'draft',
|
|
2317
|
-
});
|
|
2318
|
-
return {
|
|
2319
|
-
reply,
|
|
2320
|
-
deliveredMessageId,
|
|
2321
|
-
publicReplyText,
|
|
2322
|
-
visibleReplyBody,
|
|
2323
|
-
deliveryState: deliveredMessageId ? 'draft-finalized' : 'not-delivered',
|
|
2324
|
-
appliedAttentionSnapshot,
|
|
2325
|
-
stale: false,
|
|
2326
|
-
completed: true,
|
|
2327
|
-
};
|
|
2328
|
-
}
|
|
2329
|
-
else if (this.started && !this.controlPlaneClosed && hasVisibleText(publicReplyText)) {
|
|
2295
|
+
if (this.started && !this.controlPlaneClosed && hasVisibleText(publicReplyText)) {
|
|
2330
2296
|
const posted = await this.borgee.postMessage({
|
|
2331
2297
|
channelId,
|
|
2332
2298
|
body: visibleReplyBody,
|
|
@@ -2340,7 +2306,7 @@ export class AgentsHost {
|
|
|
2340
2306
|
controlMalformed: reply?.controlMalformed ?? false,
|
|
2341
2307
|
delivery: 'post',
|
|
2342
2308
|
});
|
|
2343
|
-
if (
|
|
2309
|
+
if (publishesCollaborationDraft) {
|
|
2344
2310
|
this.finalizeCollaborationDraft(channelId, activeTurn, posted.messageId, visibleReplyBody);
|
|
2345
2311
|
}
|
|
2346
2312
|
return {
|
|
@@ -2358,9 +2324,9 @@ export class AgentsHost {
|
|
|
2358
2324
|
...turnContext,
|
|
2359
2325
|
durationMs: Date.now() - turnStartedAt,
|
|
2360
2326
|
replyLength: publicReplyText.length,
|
|
2361
|
-
delivery:
|
|
2327
|
+
delivery: 'post',
|
|
2362
2328
|
});
|
|
2363
|
-
if (
|
|
2329
|
+
if (publishesCollaborationDraft && activeTurn?.turnExecutionId) {
|
|
2364
2330
|
this.clearCollaborationDraft(channelId, {
|
|
2365
2331
|
generation: activeTurn.generation,
|
|
2366
2332
|
turnExecutionId: activeTurn.turnExecutionId,
|
|
@@ -2378,7 +2344,6 @@ export class AgentsHost {
|
|
|
2378
2344
|
};
|
|
2379
2345
|
}
|
|
2380
2346
|
catch (error) {
|
|
2381
|
-
await this.discardDraft(channelId);
|
|
2382
2347
|
if (activeTurn?.turnExecutionId) {
|
|
2383
2348
|
this.clearCollaborationDraft(channelId, {
|
|
2384
2349
|
generation: activeTurn.generation,
|
|
@@ -2404,8 +2369,31 @@ export class AgentsHost {
|
|
|
2404
2369
|
}
|
|
2405
2370
|
finally {
|
|
2406
2371
|
stopTyping();
|
|
2372
|
+
activityReporter.end();
|
|
2407
2373
|
}
|
|
2408
2374
|
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Opens this turn's report on the activity rail.
|
|
2377
|
+
*
|
|
2378
|
+
* The generation is captured here, where the turn's own is, and every report
|
|
2379
|
+
* is checked against the channel's current turn before it leaves. That is what
|
|
2380
|
+
* keeps a superseded turn from announcing a boundary for a turn that no longer
|
|
2381
|
+
* exists — including its ending, which a window opened before it was replaced
|
|
2382
|
+
* would otherwise carry out on its behalf.
|
|
2383
|
+
*
|
|
2384
|
+
* Every turn reports, including the silent and deferred ones that deliver
|
|
2385
|
+
* nothing to the channel. The rail writes nothing anywhere, and the question
|
|
2386
|
+
* it answers — whether anything is happening in this channel — is worth the
|
|
2387
|
+
* same answer for a turn that keeps its reply to itself.
|
|
2388
|
+
*/
|
|
2389
|
+
beginTurnActivity(channelId, generation) {
|
|
2390
|
+
const reporter = this.borgee.reportTurnActivity({
|
|
2391
|
+
channelId,
|
|
2392
|
+
canReport: () => this.canAcceptTurnOutput(channelId, generation),
|
|
2393
|
+
});
|
|
2394
|
+
reporter.start();
|
|
2395
|
+
return reporter;
|
|
2396
|
+
}
|
|
2409
2397
|
canAcceptTurnOutput(channelId, generation) {
|
|
2410
2398
|
if (!this.started || this.controlPlaneClosed) {
|
|
2411
2399
|
return false;
|
|
@@ -2448,27 +2436,19 @@ export class AgentsHost {
|
|
|
2448
2436
|
this.clearProtocolFallback(channelState);
|
|
2449
2437
|
return false;
|
|
2450
2438
|
}
|
|
2451
|
-
|
|
2452
|
-
const previous = this.
|
|
2439
|
+
enqueueChannelTurn(channelId, task) {
|
|
2440
|
+
const previous = this.channelTurnQueues.get(channelId) ?? Promise.resolve();
|
|
2453
2441
|
const next = previous
|
|
2454
2442
|
.catch(() => { })
|
|
2455
2443
|
.then(task)
|
|
2456
2444
|
.finally(() => {
|
|
2457
|
-
if (this.
|
|
2458
|
-
this.
|
|
2445
|
+
if (this.channelTurnQueues.get(channelId) === next) {
|
|
2446
|
+
this.channelTurnQueues.delete(channelId);
|
|
2459
2447
|
}
|
|
2460
2448
|
});
|
|
2461
|
-
this.
|
|
2449
|
+
this.channelTurnQueues.set(channelId, next);
|
|
2462
2450
|
return next;
|
|
2463
2451
|
}
|
|
2464
|
-
ensureProgressDraft(channelId, generation, creationMetadata) {
|
|
2465
|
-
let draft = this.progressDrafts.get(channelId);
|
|
2466
|
-
if (!draft) {
|
|
2467
|
-
draft = new DraftMessageController(this.borgee, channelId, () => !this.controlPlaneClosed && this.canAcceptTurnOutput(channelId, generation), this.logger, creationMetadata);
|
|
2468
|
-
this.progressDrafts.set(channelId, draft);
|
|
2469
|
-
}
|
|
2470
|
-
return draft;
|
|
2471
|
-
}
|
|
2472
2452
|
publishCollaborationDraft(channelId, activeTurn, body) {
|
|
2473
2453
|
if (!activeTurn?.turnExecutionId || !hasVisibleText(body)) {
|
|
2474
2454
|
return;
|
|
@@ -2557,14 +2537,6 @@ export class AgentsHost {
|
|
|
2557
2537
|
}
|
|
2558
2538
|
return { ...draft.snapshot };
|
|
2559
2539
|
}
|
|
2560
|
-
async discardDraft(channelId) {
|
|
2561
|
-
const draft = this.progressDrafts.get(channelId);
|
|
2562
|
-
if (!draft) {
|
|
2563
|
-
return;
|
|
2564
|
-
}
|
|
2565
|
-
this.progressDrafts.delete(channelId);
|
|
2566
|
-
await draft.discard().catch(() => { });
|
|
2567
|
-
}
|
|
2568
2540
|
supersedeActiveTurn(channelId, activeTurn) {
|
|
2569
2541
|
if (activeTurn.superseded) {
|
|
2570
2542
|
return;
|
|
@@ -2582,7 +2554,6 @@ export class AgentsHost {
|
|
|
2582
2554
|
}
|
|
2583
2555
|
activeTurn.superseded = true;
|
|
2584
2556
|
activeTurn.turnExecutionId = null;
|
|
2585
|
-
void this.discardDraft(channelId);
|
|
2586
2557
|
}
|
|
2587
2558
|
invalidateChannelTurn(channelId) {
|
|
2588
2559
|
const activeTurn = this.collaborationChannels.get(channelId)?.activeTurn;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReportTurnActivityInput, TurnActivityReporter } from '../plugin-sdk.js';
|
|
1
2
|
import type { ChannelSummary, ChannelHistoryEntry, ChannelMessageEvent, CreateTaskInput, DirectoryUser, MeResponseUser, PostMessageInput, PostedMessage, ReadChannelHistoryInput, Task, UpdateTaskInput } from '../types.js';
|
|
2
3
|
export interface ChatControlPlane {
|
|
3
4
|
connect(onMessage: (message: ChannelMessageEvent) => void): Promise<void>;
|
|
@@ -6,6 +7,8 @@ export interface ChatControlPlane {
|
|
|
6
7
|
editMessage(messageId: string, content: string): Promise<void>;
|
|
7
8
|
deleteMessage(messageId: string): Promise<void>;
|
|
8
9
|
startTyping(channelId: string): () => void;
|
|
10
|
+
/** Opens one turn's report on the activity rail. Fire-and-forget: nothing recovers what it sends. */
|
|
11
|
+
reportTurnActivity(input: ReportTurnActivityInput): TurnActivityReporter;
|
|
9
12
|
getMe(): Promise<MeResponseUser>;
|
|
10
13
|
listUsers(): Promise<DirectoryUser[]>;
|
|
11
14
|
listChannels(): Promise<ChannelSummary[]>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type BorgeePluginClient, type BorgeePluginOptions, type InboundMessageEvent } from '../plugin-sdk.js';
|
|
1
|
+
import { type BorgeePluginClient, type BorgeePluginOptions, type InboundMessageEvent, type ReportTurnActivityInput, type TurnActivityReporter } from '../plugin-sdk.js';
|
|
2
2
|
import type { ChannelSummary, ChannelHistoryEntry, ChannelMessageEvent, CreateTaskInput, DirectoryUser, MeResponseUser, PostMessageInput, PostedMessage, ReadChannelHistoryInput, Task, UpdateTaskInput } from '../types.js';
|
|
3
3
|
import type { ChatControlPlane } from './chat-control-plane.js';
|
|
4
|
-
type PluginClientLike = Pick<BorgeePluginClient, 'agentId' | 'close' | 'connect' | 'createTask' | 'deleteMessage' | 'editMessage' | 'getMe' | 'getTask' | 'listChannels' | 'listTasks' | 'listUsers' | 'on' | 'readHistory' | 'sendMessage' | 'startTyping' | 'updateTask' | 'setTaskProperty' | 'deleteTaskProperty'>;
|
|
4
|
+
type PluginClientLike = Pick<BorgeePluginClient, 'agentId' | 'close' | 'connect' | 'createTask' | 'deleteMessage' | 'editMessage' | 'getMe' | 'getTask' | 'listChannels' | 'listTasks' | 'listUsers' | 'on' | 'readHistory' | 'reportTurnActivity' | 'sendMessage' | 'startTyping' | 'updateTask' | 'setTaskProperty' | 'deleteTaskProperty'>;
|
|
5
5
|
type PluginClientFactory = (options: BorgeePluginOptions) => PluginClientLike;
|
|
6
|
-
type SdkChatControlPlaneOptions = Pick<BorgeePluginOptions, '
|
|
6
|
+
type SdkChatControlPlaneOptions = Pick<BorgeePluginOptions, 'pluginId'>;
|
|
7
7
|
/**
|
|
8
8
|
* Thin adapter over `@borgee/plugin-sdk` (the same BPP/`/ws/plugin` SDK used by
|
|
9
9
|
* the OpenClaw plugin) that implements the minimal `ChatControlPlane` surface
|
|
@@ -22,6 +22,7 @@ export declare class SdkChatControlPlane implements ChatControlPlane {
|
|
|
22
22
|
editMessage(messageId: string, content: string): Promise<void>;
|
|
23
23
|
deleteMessage(messageId: string): Promise<void>;
|
|
24
24
|
startTyping(channelId: string): () => void;
|
|
25
|
+
reportTurnActivity(input: ReportTurnActivityInput): TurnActivityReporter;
|
|
25
26
|
getMe(): Promise<MeResponseUser>;
|
|
26
27
|
listUsers(): Promise<DirectoryUser[]>;
|
|
27
28
|
readChannelHistory(input: ReadChannelHistoryInput): Promise<ChannelHistoryEntry[]>;
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { realpathSync } from 'node:fs';
|
|
3
|
-
import {
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { assertNoUpdateArgs, CliUsageError, parseApplyManagedArgs, parseDaemonArgs, parseDescribeArgs, parseDescribeManagedArgs, parseCleanupManagedArgs, parseGenerateConfigArgs, parseLogArgs, parseManagedStartArgs, parsePrintLayoutArgs, parseStartArgs, parseValidateArgs, USAGE, } from './cli-args.js';
|
|
6
6
|
import { resolveAgentsHostDebugMode } from './debug.js';
|
|
@@ -15,7 +15,6 @@ function formatErrorMessage(error) {
|
|
|
15
15
|
}
|
|
16
16
|
return String(error);
|
|
17
17
|
}
|
|
18
|
-
const TASK_WORKSPACE_ROOT_DIR_ENV = 'AGENTS_HOST_INTERNAL_TASK_WORKSPACE_ROOT_DIR';
|
|
19
18
|
export async function dispatchCli(argv, deps = {}) {
|
|
20
19
|
const [command, ...rest] = argv;
|
|
21
20
|
const env = deps.env ?? process.env;
|
|
@@ -31,7 +30,6 @@ export async function dispatchCli(argv, deps = {}) {
|
|
|
31
30
|
const applyManagedSpecImpl = deps.applyManagedSpec ?? applyManagedSpec;
|
|
32
31
|
const startManagedDaemonImpl = deps.startManagedDaemon ??
|
|
33
32
|
(async (rootPath, debug) => {
|
|
34
|
-
env[TASK_WORKSPACE_ROOT_DIR_ENV] = rootPath;
|
|
35
33
|
const daemon = new ManagedAgentsHostDaemon(rootPath, debug, {
|
|
36
34
|
logPath: env.AGENTS_HOST_MANAGED_DAEMON_LOG_PATH,
|
|
37
35
|
});
|
|
@@ -63,7 +61,6 @@ export async function dispatchCli(argv, deps = {}) {
|
|
|
63
61
|
await runMainImpl({ debug });
|
|
64
62
|
return;
|
|
65
63
|
}
|
|
66
|
-
env[TASK_WORKSPACE_ROOT_DIR_ENV] = dirname(resolve(parsed.configPath));
|
|
67
64
|
await runMainImpl({ configPath: parsed.configPath, debug });
|
|
68
65
|
return;
|
|
69
66
|
}
|
|
@@ -167,7 +164,6 @@ export async function dispatchCli(argv, deps = {}) {
|
|
|
167
164
|
}
|
|
168
165
|
if (command === 'daemon') {
|
|
169
166
|
const parsed = parseDaemonArgs(rest);
|
|
170
|
-
env[TASK_WORKSPACE_ROOT_DIR_ENV] = parsed.rootPath;
|
|
171
167
|
await startManagedDaemonImpl(parsed.rootPath, parsed.debug);
|
|
172
168
|
return;
|
|
173
169
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProjectionStrategy } from './types.js';
|
|
1
2
|
export declare const CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE = "claude-provider-v2";
|
|
2
3
|
export declare const COPILOT_PROVIDER_V2_COMPATIBILITY_GATE = "copilot-provider-v2";
|
|
3
4
|
export declare const CODEX_PROVIDER_COMPATIBILITY_GATE = "codex-provider";
|
|
@@ -18,6 +19,7 @@ export declare const COMPATIBILITY_GATES_ENV = "AGENTS_HOST_INTERNAL_COMPATIBILI
|
|
|
18
19
|
export declare const INTERNAL_DISABLED_COMPATIBILITY_GATES_ENV = "AGENTS_HOST_INTERNAL_DISABLED_COMPATIBILITY_GATES";
|
|
19
20
|
export declare const INTERNAL_POLICY_MODE_ENV = "AGENTS_HOST_INTERNAL_POLICY_MODE";
|
|
20
21
|
export declare const INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV = "AGENTS_HOST_INTERNAL_PROVIDER_IMPLEMENTATIONS";
|
|
22
|
+
export declare const INTERNAL_CLAUDE_PROMPT_STRATEGY_ENV = "AGENTS_HOST_INTERNAL_CLAUDE_PROMPT_STRATEGY";
|
|
21
23
|
export declare const MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION = 1;
|
|
22
24
|
export type InternalPolicyMode = 'audit-only' | 'enforce';
|
|
23
25
|
export type InternalProviderImplementationPath = 'v1' | 'v2';
|
|
@@ -28,8 +30,10 @@ export interface ManagedRuntimeSettingsSnapshot {
|
|
|
28
30
|
compatibilityGates: string[];
|
|
29
31
|
providerImplementationOverrides: string[];
|
|
30
32
|
internalPolicyMode: InternalPolicyMode;
|
|
33
|
+
projectionStrategy: ProjectionStrategy;
|
|
31
34
|
}
|
|
32
35
|
export declare const DEFAULT_INTERNAL_COMPATIBILITY_GATES: readonly string[];
|
|
36
|
+
export declare function resolveInternalProjectionStrategy(env?: NodeJS.ProcessEnv): ProjectionStrategy;
|
|
33
37
|
export declare function parseCompatibilityGates(rawValue: string | undefined): ReadonlySet<string>;
|
|
34
38
|
export declare function resolveInternalCompatibilityGates(env?: NodeJS.ProcessEnv): ReadonlySet<string>;
|
|
35
39
|
export declare function resolveDisabledDefaultCompatibilityGates(compatibilityGates: Iterable<string>): string[];
|