@borgee/agents-host 0.2.62 → 0.2.68
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/agents-host.d.ts +3 -1
- package/dist/agents-host.js +126 -11
- package/dist/chat/chat-control-plane.d.ts +2 -1
- package/dist/chat/sdk-chat-control-plane.d.ts +3 -2
- package/dist/chat/sdk-chat-control-plane.js +4 -0
- package/dist/compatibility-gates.d.ts +2 -0
- package/dist/compatibility-gates.js +13 -0
- package/dist/context/prompt.js +0 -2
- package/dist/managed-daemon.js +5 -1
- package/dist/plugin-sdk.js +23 -10
- package/dist/plugin-sdk.js.map +2 -2
- package/dist/providers/claude/adapter.d.ts +1 -0
- package/dist/providers/claude/adapter.js +3 -0
- package/dist/providers/claude/cli-client.d.ts +1 -0
- package/dist/providers/claude/cli-client.js +23 -0
- package/dist/providers/codex/adapter.d.ts +1 -0
- package/dist/providers/codex/adapter.js +3 -0
- package/dist/providers/codex/cli-client.d.ts +1 -0
- package/dist/providers/codex/cli-client.js +25 -1
- package/dist/providers/copilot/adapter.d.ts +1 -0
- package/dist/providers/copilot/adapter.js +3 -0
- package/dist/providers/copilot/cli-client.d.ts +1 -0
- package/dist/providers/copilot/cli-client.js +21 -0
- package/dist/providers/create-provider.js +6 -0
- package/dist/providers/provider-adapter.d.ts +7 -0
- package/dist/providers/provider-adapter.js +8 -0
- package/package.json +2 -2
package/dist/agents-host.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChatControlPlane } from './chat/chat-control-plane.js';
|
|
2
2
|
import { type AgentsHostRuntimeOptions } from './debug.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type ProviderAdapter } from './providers/provider-adapter.js';
|
|
4
4
|
import type { AgentsHostConfig } from './types.js';
|
|
5
5
|
/**
|
|
6
6
|
* Minimal single-agent agents host: connects one local Claude/Copilot CLI
|
|
@@ -160,6 +160,8 @@ export declare class AgentsHost {
|
|
|
160
160
|
private readCollaborationDraft;
|
|
161
161
|
private supersedeActiveTurn;
|
|
162
162
|
private invalidateChannelTurn;
|
|
163
|
+
private stopTurn;
|
|
164
|
+
private responseStateForExecuted;
|
|
163
165
|
private rememberRecentTurn;
|
|
164
166
|
private resolveAuthorizedCollaborationTurn;
|
|
165
167
|
private updateAwaitingUserState;
|
package/dist/agents-host.js
CHANGED
|
@@ -12,6 +12,7 @@ import { createLocalhostGatewayController, LOCALHOST_GATEWAY_COLLABORATION_TARGE
|
|
|
12
12
|
import { extractTaskIdFromTaskAssignmentContent, resolveTaskAssignmentStatePath, } from './context/injection.js';
|
|
13
13
|
import { AuthorizationAuditSink, } from './policy/authorization-audit.js';
|
|
14
14
|
import { createProvider } from './providers/create-provider.js';
|
|
15
|
+
import { ProviderTurnCancelledError } from './providers/provider-adapter.js';
|
|
15
16
|
import { resolveAttentionStatePath, resolveCompactionStatePath, resolveSharedProtocolKickoffDecisionPath, resolveSharedProtocolStatusPath, } from './state-paths.js';
|
|
16
17
|
import { appendVisibleMention as appendVisibleBodyMention, extractVisibleMentionIds as extractCanonicalMentionIds, } from './visible-mentions.js';
|
|
17
18
|
import { buildHostedIncomingContentText, buildHostedTurnContentParts, extractHostedMessageAttachments, normalizeHostedMessageAttachment, } from './hosted-turn-content.js';
|
|
@@ -24,6 +25,9 @@ const PROTOCOL_KICKOFF_DECISION_POLL_INTERVAL_MS = 50;
|
|
|
24
25
|
const PROTOCOL_KICKOFF_ROUND_LIMIT = 20;
|
|
25
26
|
const COLLABORATION_LATE_SEND_GRACE_MS = 5_000;
|
|
26
27
|
const ORDINARY_HUMAN_EVENT_KINDS = new Set(['', 'message']);
|
|
28
|
+
const TASK_EXECUTION_LOCAL_DIRECTORY_PROPERTY_KEY = 'execution.local_directory';
|
|
29
|
+
const TASK_EXECUTION_LOCAL_DIRECTORY_REMINDER = 'This task has no Execution Local Directory yet. Set it before asking me to work in a real local project directory.';
|
|
30
|
+
const TASK_EXECUTION_LOCAL_DIRECTORY_IN_USE_PREFIX = 'Using Execution Local Directory:';
|
|
27
31
|
async function ensurePrivateStateRoot(path) {
|
|
28
32
|
await mkdir(path, { recursive: true, mode: PRIVATE_STATE_ROOT_MODE });
|
|
29
33
|
await chmod(path, PRIVATE_STATE_ROOT_MODE);
|
|
@@ -145,13 +149,15 @@ class DefaultHostRuntime {
|
|
|
145
149
|
});
|
|
146
150
|
this.ensureStateRoot = deps.ensureStateRoot ?? ensurePrivateStateRoot;
|
|
147
151
|
}
|
|
148
|
-
async start(onMessage) {
|
|
152
|
+
async start(onMessage, onStopTurn) {
|
|
149
153
|
await this.ensureStateRoot(this.config.stateRootDir);
|
|
150
154
|
await this.gateway.start();
|
|
151
155
|
try {
|
|
156
|
+
this.controlPlane.onStopTurn?.(onStopTurn);
|
|
152
157
|
await this.controlPlane.connect(onMessage);
|
|
153
158
|
}
|
|
154
159
|
catch (error) {
|
|
160
|
+
this.controlPlane.onStopTurn?.(undefined);
|
|
155
161
|
await this.gateway.stop().catch(() => { });
|
|
156
162
|
throw error;
|
|
157
163
|
}
|
|
@@ -159,6 +165,7 @@ class DefaultHostRuntime {
|
|
|
159
165
|
async stop() {
|
|
160
166
|
let thrown;
|
|
161
167
|
try {
|
|
168
|
+
this.controlPlane.onStopTurn?.(undefined);
|
|
162
169
|
await this.controlPlane.close();
|
|
163
170
|
}
|
|
164
171
|
catch (error) {
|
|
@@ -366,7 +373,7 @@ export class AgentsHost {
|
|
|
366
373
|
return;
|
|
367
374
|
}
|
|
368
375
|
this.dispatchMessage(message);
|
|
369
|
-
});
|
|
376
|
+
}, async (channelId) => this.stopTurn(channelId));
|
|
370
377
|
const agentId = await this.ensureSelfAgentId();
|
|
371
378
|
bufferingMessages = false;
|
|
372
379
|
while (bufferedMessages.length > 0) {
|
|
@@ -675,7 +682,7 @@ export class AgentsHost {
|
|
|
675
682
|
return null;
|
|
676
683
|
}
|
|
677
684
|
this.recordCollaborationOutcome(msg.channel_id, {
|
|
678
|
-
responseState: executed
|
|
685
|
+
responseState: this.responseStateForExecuted(executed),
|
|
679
686
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
680
687
|
});
|
|
681
688
|
this.updateMissedCollaborationDiagnostic(msg.channel_id, priorMissedCollaborationDiagnostic);
|
|
@@ -1110,7 +1117,7 @@ export class AgentsHost {
|
|
|
1110
1117
|
channelState.blocked = undefined;
|
|
1111
1118
|
this.awaitingUserByChannel.delete(channelId);
|
|
1112
1119
|
this.recordCollaborationOutcome(channelId, {
|
|
1113
|
-
responseState: executed
|
|
1120
|
+
responseState: this.responseStateForExecuted(executed),
|
|
1114
1121
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
1115
1122
|
...(message.wakeBlockedState ? { wakeState: 'resumed-human' } : {}),
|
|
1116
1123
|
turnExecutionId: activeTurn.turnExecutionId ?? undefined,
|
|
@@ -1174,7 +1181,7 @@ export class AgentsHost {
|
|
|
1174
1181
|
const visibleMessageId = deliveredMessageId ?? protocolState.lastProtocolMessageId;
|
|
1175
1182
|
if (executed.reply?.controlMalformed) {
|
|
1176
1183
|
this.recordCollaborationOutcome(channelId, {
|
|
1177
|
-
responseState: executed
|
|
1184
|
+
responseState: this.responseStateForExecuted(executed),
|
|
1178
1185
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
1179
1186
|
...(message.wakeBlockedState ? { wakeState: 'resumed-human' } : {}),
|
|
1180
1187
|
turnExecutionId: activeTurn.turnExecutionId ?? undefined,
|
|
@@ -1184,7 +1191,7 @@ export class AgentsHost {
|
|
|
1184
1191
|
}
|
|
1185
1192
|
if (!executed.reply?.control) {
|
|
1186
1193
|
this.recordCollaborationOutcome(channelId, {
|
|
1187
|
-
responseState: executed
|
|
1194
|
+
responseState: this.responseStateForExecuted(executed),
|
|
1188
1195
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
1189
1196
|
...(message.wakeBlockedState ? { wakeState: 'resumed-human' } : {}),
|
|
1190
1197
|
turnExecutionId: activeTurn.turnExecutionId ?? undefined,
|
|
@@ -1218,7 +1225,7 @@ export class AgentsHost {
|
|
|
1218
1225
|
}
|
|
1219
1226
|
if (executed.reply.control.kind === 'start-protocol') {
|
|
1220
1227
|
this.recordCollaborationOutcome(channelId, {
|
|
1221
|
-
responseState: executed
|
|
1228
|
+
responseState: this.responseStateForExecuted(executed),
|
|
1222
1229
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
1223
1230
|
...(message.wakeBlockedState ? { wakeState: 'resumed-human' } : {}),
|
|
1224
1231
|
turnExecutionId: activeTurn.turnExecutionId ?? undefined,
|
|
@@ -1229,7 +1236,7 @@ export class AgentsHost {
|
|
|
1229
1236
|
}
|
|
1230
1237
|
if (executed.reply.control.kind === 'attention-only') {
|
|
1231
1238
|
this.recordCollaborationOutcome(channelId, {
|
|
1232
|
-
responseState: executed
|
|
1239
|
+
responseState: this.responseStateForExecuted(executed),
|
|
1233
1240
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
1234
1241
|
...(message.wakeBlockedState ? { wakeState: 'resumed-human' } : {}),
|
|
1235
1242
|
turnExecutionId: activeTurn.turnExecutionId ?? undefined,
|
|
@@ -2188,9 +2195,7 @@ export class AgentsHost {
|
|
|
2188
2195
|
this.recordCollaborationOutcome(msg.channel_id, {
|
|
2189
2196
|
responseState: executed.completed && executed.reply?.awaitingUser
|
|
2190
2197
|
? 'blocked'
|
|
2191
|
-
: executed
|
|
2192
|
-
? 'responded'
|
|
2193
|
-
: 'failed',
|
|
2198
|
+
: this.responseStateForExecuted(executed),
|
|
2194
2199
|
deliveryState: executed.deliveryState ?? 'not-delivered',
|
|
2195
2200
|
...(executed.completed && executed.reply?.awaitingUser
|
|
2196
2201
|
? {
|
|
@@ -2444,6 +2449,65 @@ export class AgentsHost {
|
|
|
2444
2449
|
turnExecutionId: activeTurn.turnExecutionId,
|
|
2445
2450
|
});
|
|
2446
2451
|
}
|
|
2452
|
+
if (error instanceof ProviderTurnCancelledError) {
|
|
2453
|
+
const cancelledReplyText = error.publicReplyText?.trim();
|
|
2454
|
+
if (!silentTurn &&
|
|
2455
|
+
!deferDelivery &&
|
|
2456
|
+
typeof cancelledReplyText === 'string' &&
|
|
2457
|
+
cancelledReplyText.length > 0 &&
|
|
2458
|
+
this.started &&
|
|
2459
|
+
!this.controlPlaneClosed) {
|
|
2460
|
+
reply = { text: cancelledReplyText };
|
|
2461
|
+
publicReplyText = cancelledReplyText;
|
|
2462
|
+
visibleReplyBody = this.resolveVisibleTurnBody(activeTurn, reply, publicReplyText);
|
|
2463
|
+
try {
|
|
2464
|
+
const posted = await this.borgee.postMessage({
|
|
2465
|
+
channelId,
|
|
2466
|
+
body: visibleReplyBody,
|
|
2467
|
+
replyToId: activeTurn?.delivery?.replyToId,
|
|
2468
|
+
});
|
|
2469
|
+
this.logger.debug('posted cancelled turn feedback', {
|
|
2470
|
+
...turnContext,
|
|
2471
|
+
durationMs: Date.now() - turnStartedAt,
|
|
2472
|
+
replyLength: publicReplyText.length,
|
|
2473
|
+
delivery: 'post',
|
|
2474
|
+
});
|
|
2475
|
+
return {
|
|
2476
|
+
reply,
|
|
2477
|
+
deliveredMessageId: posted.messageId,
|
|
2478
|
+
publicReplyText,
|
|
2479
|
+
visibleReplyBody,
|
|
2480
|
+
deliveryState: 'posted',
|
|
2481
|
+
stale: activeTurn?.superseded === true,
|
|
2482
|
+
completed: false,
|
|
2483
|
+
cancelled: true,
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
catch (postError) {
|
|
2487
|
+
this.logger.debugError('failed to post cancelled turn feedback', {
|
|
2488
|
+
...turnContext,
|
|
2489
|
+
error: postError,
|
|
2490
|
+
});
|
|
2491
|
+
this.logger.error('failed to post cancelled turn feedback', {
|
|
2492
|
+
...turnContext,
|
|
2493
|
+
error: summarizeError(postError),
|
|
2494
|
+
});
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
this.logger.debug('cancelled turn', {
|
|
2498
|
+
...turnContext,
|
|
2499
|
+
durationMs: Date.now() - turnStartedAt,
|
|
2500
|
+
});
|
|
2501
|
+
return {
|
|
2502
|
+
reply,
|
|
2503
|
+
publicReplyText,
|
|
2504
|
+
visibleReplyBody,
|
|
2505
|
+
deliveryState: 'not-delivered',
|
|
2506
|
+
stale: activeTurn?.superseded === true,
|
|
2507
|
+
completed: false,
|
|
2508
|
+
cancelled: true,
|
|
2509
|
+
};
|
|
2510
|
+
}
|
|
2447
2511
|
this.logger.debugError('failed to generate or send reply', {
|
|
2448
2512
|
...turnContext,
|
|
2449
2513
|
error,
|
|
@@ -2655,6 +2719,29 @@ export class AgentsHost {
|
|
|
2655
2719
|
activeTurn.turnExecutionId = null;
|
|
2656
2720
|
}
|
|
2657
2721
|
}
|
|
2722
|
+
async stopTurn(channelId) {
|
|
2723
|
+
const activeTurn = this.collaborationChannels.get(channelId)?.activeTurn;
|
|
2724
|
+
const aborted = await this.provider.cancelTurn?.(channelId) ?? false;
|
|
2725
|
+
if (!aborted) {
|
|
2726
|
+
return { aborted: false };
|
|
2727
|
+
}
|
|
2728
|
+
if (activeTurn) {
|
|
2729
|
+
this.supersedeActiveTurn(channelId, activeTurn);
|
|
2730
|
+
}
|
|
2731
|
+
else {
|
|
2732
|
+
this.recordCollaborationOutcome(channelId, {
|
|
2733
|
+
responseState: 'superseded',
|
|
2734
|
+
deliveryState: 'not-delivered',
|
|
2735
|
+
});
|
|
2736
|
+
}
|
|
2737
|
+
return { aborted: true };
|
|
2738
|
+
}
|
|
2739
|
+
responseStateForExecuted(executed) {
|
|
2740
|
+
if (executed.cancelled) {
|
|
2741
|
+
return 'superseded';
|
|
2742
|
+
}
|
|
2743
|
+
return executed.completed ? 'responded' : 'failed';
|
|
2744
|
+
}
|
|
2658
2745
|
rememberRecentTurn(channelState, activeTurn) {
|
|
2659
2746
|
if (!activeTurn.turnExecutionId) {
|
|
2660
2747
|
channelState.recentTurn = undefined;
|
|
@@ -2853,6 +2940,34 @@ export class AgentsHost {
|
|
|
2853
2940
|
task = null;
|
|
2854
2941
|
}
|
|
2855
2942
|
if (task && task.assigneeId === selfAgentId) {
|
|
2943
|
+
const executionLocalDirectory = task.properties?.[TASK_EXECUTION_LOCAL_DIRECTORY_PROPERTY_KEY];
|
|
2944
|
+
if (typeof executionLocalDirectory !== 'string' || executionLocalDirectory.trim().length === 0) {
|
|
2945
|
+
try {
|
|
2946
|
+
await this.borgee.postMessage({
|
|
2947
|
+
channelId: msg.channel_id,
|
|
2948
|
+
body: TASK_EXECUTION_LOCAL_DIRECTORY_REMINDER,
|
|
2949
|
+
});
|
|
2950
|
+
}
|
|
2951
|
+
catch (error) {
|
|
2952
|
+
this.logger.debugError('task local directory reminder post failed', {
|
|
2953
|
+
channelId: msg.channel_id,
|
|
2954
|
+
error,
|
|
2955
|
+
});
|
|
2956
|
+
}
|
|
2957
|
+
return null;
|
|
2958
|
+
}
|
|
2959
|
+
try {
|
|
2960
|
+
await this.borgee.postMessage({
|
|
2961
|
+
channelId: msg.channel_id,
|
|
2962
|
+
body: `${TASK_EXECUTION_LOCAL_DIRECTORY_IN_USE_PREFIX} ${executionLocalDirectory}`,
|
|
2963
|
+
});
|
|
2964
|
+
}
|
|
2965
|
+
catch (error) {
|
|
2966
|
+
this.logger.debugError('task local directory notice post failed', {
|
|
2967
|
+
channelId: msg.channel_id,
|
|
2968
|
+
error,
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2856
2971
|
if (task.status === 'open') {
|
|
2857
2972
|
try {
|
|
2858
2973
|
await this.borgee.updateTask({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { ReportTurnActivityInput, TurnActivityReporter } from '../plugin-sdk.js';
|
|
1
|
+
import type { ReportTurnActivityInput, StopTurnHandler, 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
|
export interface ChatControlPlane {
|
|
4
|
+
onStopTurn?(handler: StopTurnHandler | undefined): void;
|
|
4
5
|
connect(onMessage: (message: ChannelMessageEvent) => void): Promise<void>;
|
|
5
6
|
close(): Promise<void>;
|
|
6
7
|
postMessage(input: PostMessageInput): Promise<PostedMessage>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type BorgeePluginClient, type BorgeePluginOptions, type InboundMessageEvent, type ReportTurnActivityInput, type TurnActivityReporter } from '../plugin-sdk.js';
|
|
1
|
+
import { type BorgeePluginClient, type BorgeePluginOptions, type InboundMessageEvent, type ReportTurnActivityInput, type StopTurnHandler, 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' | 'reportTurnActivity' | 'sendMessage' | 'startTyping' | 'updateTask' | 'setTaskProperty' | 'deleteTaskProperty'>;
|
|
4
|
+
type PluginClientLike = Pick<BorgeePluginClient, 'agentId' | 'close' | 'connect' | 'createTask' | 'deleteMessage' | 'editMessage' | 'getMe' | 'getTask' | 'listChannels' | 'listTasks' | 'listUsers' | 'on' | 'onStopTurn' | 'readHistory' | 'reportTurnActivity' | 'sendMessage' | 'startTyping' | 'updateTask' | 'setTaskProperty' | 'deleteTaskProperty'>;
|
|
5
5
|
type PluginClientFactory = (options: BorgeePluginOptions) => PluginClientLike;
|
|
6
6
|
type SdkChatControlPlaneOptions = Pick<BorgeePluginOptions, 'pluginId'>;
|
|
7
7
|
/**
|
|
@@ -16,6 +16,7 @@ export declare class SdkChatControlPlane implements ChatControlPlane {
|
|
|
16
16
|
private connected;
|
|
17
17
|
private me;
|
|
18
18
|
constructor(baseUrl: string, apiKey: string, createClient?: PluginClientFactory, options?: SdkChatControlPlaneOptions);
|
|
19
|
+
onStopTurn(handler: StopTurnHandler | undefined): void;
|
|
19
20
|
connect(onMessage: (message: ChannelMessageEvent) => void): Promise<void>;
|
|
20
21
|
close(): Promise<void>;
|
|
21
22
|
postMessage(input: PostMessageInput): Promise<PostedMessage>;
|
|
@@ -14,6 +14,9 @@ export class SdkChatControlPlane {
|
|
|
14
14
|
constructor(baseUrl, apiKey, createClient = createBorgeePlugin, options = {}) {
|
|
15
15
|
this.client = createClient({ baseUrl, apiKey, ...options });
|
|
16
16
|
}
|
|
17
|
+
onStopTurn(handler) {
|
|
18
|
+
this.client.onStopTurn(handler);
|
|
19
|
+
}
|
|
17
20
|
async connect(onMessage) {
|
|
18
21
|
this.unsubscribe = this.client.on('message', (event) => {
|
|
19
22
|
const message = mapInboundToChannelMessage(event);
|
|
@@ -46,6 +49,7 @@ export class SdkChatControlPlane {
|
|
|
46
49
|
this.pendingMessages = [];
|
|
47
50
|
this.unsubscribe?.();
|
|
48
51
|
this.unsubscribe = null;
|
|
52
|
+
this.client.onStopTurn(undefined);
|
|
49
53
|
await this.client.close();
|
|
50
54
|
}
|
|
51
55
|
async postMessage(input) {
|
|
@@ -25,12 +25,14 @@ export type InternalPolicyMode = 'audit-only' | 'enforce';
|
|
|
25
25
|
export type InternalProviderImplementationPath = 'v1' | 'v2';
|
|
26
26
|
export type InternalProviderImplementationKey = 'claude' | 'copilot';
|
|
27
27
|
export type InternalProviderImplementationOverrides = Partial<Record<InternalProviderImplementationKey, InternalProviderImplementationPath>>;
|
|
28
|
+
export declare const CURRENT_AGENTS_HOST_PACKAGE_VERSION: string;
|
|
28
29
|
export interface ManagedRuntimeSettingsSnapshot {
|
|
29
30
|
schemaVersion: number;
|
|
30
31
|
compatibilityGates: string[];
|
|
31
32
|
providerImplementationOverrides: string[];
|
|
32
33
|
internalPolicyMode: InternalPolicyMode;
|
|
33
34
|
projectionStrategy: ProjectionStrategy;
|
|
35
|
+
packageVersion: string;
|
|
34
36
|
}
|
|
35
37
|
export declare const DEFAULT_INTERNAL_COMPATIBILITY_GATES: readonly string[];
|
|
36
38
|
export declare function resolveInternalProjectionStrategy(env?: NodeJS.ProcessEnv): ProjectionStrategy;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
2
5
|
import { DEFAULT_PROJECTION_STRATEGY, normalizeProjectionStrategy, } from './projection-strategy-values.js';
|
|
3
6
|
export const CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE = 'claude-provider-v2';
|
|
4
7
|
export const COPILOT_PROVIDER_V2_COMPATIBILITY_GATE = 'copilot-provider-v2';
|
|
@@ -22,6 +25,15 @@ export const INTERNAL_POLICY_MODE_ENV = 'AGENTS_HOST_INTERNAL_POLICY_MODE';
|
|
|
22
25
|
export const INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV = 'AGENTS_HOST_INTERNAL_PROVIDER_IMPLEMENTATIONS';
|
|
23
26
|
export const INTERNAL_CLAUDE_PROMPT_STRATEGY_ENV = 'AGENTS_HOST_INTERNAL_CLAUDE_PROMPT_STRATEGY';
|
|
24
27
|
export const MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION = 1;
|
|
28
|
+
function readCurrentAgentsHostPackageVersion() {
|
|
29
|
+
const packageManifestPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
30
|
+
const manifest = JSON.parse(readFileSync(packageManifestPath, 'utf8'));
|
|
31
|
+
if (typeof manifest.version !== 'string' || manifest.version.length === 0) {
|
|
32
|
+
throw new Error(`Unable to resolve agents-host package version from ${packageManifestPath}`);
|
|
33
|
+
}
|
|
34
|
+
return manifest.version;
|
|
35
|
+
}
|
|
36
|
+
export const CURRENT_AGENTS_HOST_PACKAGE_VERSION = readCurrentAgentsHostPackageVersion();
|
|
25
37
|
const VALID_PROVIDER_IMPLEMENTATION_ENTRIES = '"claude:v1", "claude:v2", "copilot:v1", or "copilot:v2"';
|
|
26
38
|
export const DEFAULT_INTERNAL_COMPATIBILITY_GATES = Object.freeze([
|
|
27
39
|
ATTENTION_FOLLOW_SEMANTICS_COMPATIBILITY_GATE,
|
|
@@ -176,6 +188,7 @@ export function resolveManagedRuntimeSettingsSnapshot(env = process.env) {
|
|
|
176
188
|
providerImplementationOverrides: resolveManagedRuntimeProviderImplementationOverrides(env, compatibilityGates),
|
|
177
189
|
internalPolicyMode: resolveInternalPolicyMode(compatibilityGates.includes(POLICY_AUDIT_ENFORCEMENT_COMPATIBILITY_GATE), env),
|
|
178
190
|
projectionStrategy: resolveInternalProjectionStrategy(env),
|
|
191
|
+
packageVersion: CURRENT_AGENTS_HOST_PACKAGE_VERSION,
|
|
179
192
|
};
|
|
180
193
|
}
|
|
181
194
|
export function serializeManagedRuntimeSettingsSnapshot(snapshot) {
|
package/dist/context/prompt.js
CHANGED
|
@@ -565,9 +565,7 @@ function buildClaudeZeroTurnPrompt(params) {
|
|
|
565
565
|
}
|
|
566
566
|
const gatewayTaskLines = buildClaudeOrdinaryGatewayTaskLines(params.promptContext);
|
|
567
567
|
return [
|
|
568
|
-
'Do not claim to have performed actions you did not actually perform.',
|
|
569
568
|
...(gatewayTaskLines.length > 0 ? [...gatewayTaskLines, ''] : []),
|
|
570
|
-
`New message from ${params.incomingAuthorId}:`,
|
|
571
569
|
params.incomingContent,
|
|
572
570
|
].join('\n');
|
|
573
571
|
}
|
package/dist/managed-daemon.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
import { AgentsHostSupervisor } from './agents-host-supervisor.js';
|
|
8
8
|
import { DEFAULT_PROJECTION_STRATEGY, normalizeProjectionStrategy, } from './projection-strategy-values.js';
|
|
9
9
|
import { resolveChannelWorkspaceDirectory, resolveChannelWorkspaceRootDirectory, resolveManagedWorkspaceCollectionRoot, resolveTaskThreadScratchWorkspaceDirectory, } from './context/injection.js';
|
|
10
|
-
import { CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE, COMPATIBILITY_GATES_ENV, createManagedRuntimeSettingsFingerprint, INTERNAL_CLAUDE_PROMPT_STRATEGY_ENV, INTERNAL_DISABLED_COMPATIBILITY_GATES_ENV, INTERNAL_POLICY_MODE_ENV, INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV, MANAGED_RUNTIME_CONVERGENCE_COMPATIBILITY_GATE, MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION, resolveDisabledDefaultCompatibilityGates, resolveManagedRuntimeSettingsSnapshot, serializeManagedRuntimeSettingsSnapshot, normalizeInternalProviderImplementationOverrides, } from './compatibility-gates.js';
|
|
10
|
+
import { CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE, COMPATIBILITY_GATES_ENV, CURRENT_AGENTS_HOST_PACKAGE_VERSION, createManagedRuntimeSettingsFingerprint, INTERNAL_CLAUDE_PROMPT_STRATEGY_ENV, INTERNAL_DISABLED_COMPATIBILITY_GATES_ENV, INTERNAL_POLICY_MODE_ENV, INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV, MANAGED_RUNTIME_CONVERGENCE_COMPATIBILITY_GATE, MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION, resolveDisabledDefaultCompatibilityGates, resolveManagedRuntimeSettingsSnapshot, serializeManagedRuntimeSettingsSnapshot, normalizeInternalProviderImplementationOverrides, } from './compatibility-gates.js';
|
|
11
11
|
import { DEFAULT_PROVIDER_COMMAND_CONFIG, hasLegacyClaudeOneShotArgs, loadConfigFromEnv, } from './config.js';
|
|
12
12
|
import { loadLocalConfigGenerateSpec, materializeLocalConfig, parseGenerateConfigSpec, resolveLocalConfigLayout, } from './local-config.js';
|
|
13
13
|
import { normalizeManagedRuntimeKey, resolveManagedBootstrapLockPath, resolveManagedDaemonEndpoint, resolveManagedDaemonLogPath, resolveManagedRuntimeRoot, resolveManagedStateRoot, resolveManagedRuntimeSettingsPath, } from './state-paths.js';
|
|
@@ -163,6 +163,7 @@ function normalizeManagedRuntimeSettingsSnapshot(snapshot) {
|
|
|
163
163
|
providerImplementationOverrides,
|
|
164
164
|
internalPolicyMode: snapshot.internalPolicyMode,
|
|
165
165
|
projectionStrategy: snapshot.projectionStrategy ?? DEFAULT_PROJECTION_STRATEGY,
|
|
166
|
+
packageVersion: CURRENT_AGENTS_HOST_PACKAGE_VERSION,
|
|
166
167
|
};
|
|
167
168
|
}
|
|
168
169
|
function parseManagedRuntimeSettingsSnapshotRecord(value, sourceLabel) {
|
|
@@ -197,6 +198,9 @@ function parseManagedRuntimeSettingsSnapshotRecord(value, sourceLabel) {
|
|
|
197
198
|
providerImplementationOverrides: [...record.providerImplementationOverrides],
|
|
198
199
|
internalPolicyMode: record.internalPolicyMode,
|
|
199
200
|
projectionStrategy: projectionStrategy ?? DEFAULT_PROJECTION_STRATEGY,
|
|
201
|
+
packageVersion: typeof record.packageVersion === 'string' && record.packageVersion.trim().length > 0
|
|
202
|
+
? record.packageVersion
|
|
203
|
+
: CURRENT_AGENTS_HOST_PACKAGE_VERSION,
|
|
200
204
|
});
|
|
201
205
|
}
|
|
202
206
|
async function loadManagedRuntimeSettingsSnapshot(rootPath) {
|
package/dist/plugin-sdk.js
CHANGED
|
@@ -3777,7 +3777,6 @@ var BppTransport = class {
|
|
|
3777
3777
|
// send issued during a reconnect never races ahead of the handshake.
|
|
3778
3778
|
online = false;
|
|
3779
3779
|
terminal = false;
|
|
3780
|
-
inboundFailed = false;
|
|
3781
3780
|
inboundChain = Promise.resolve();
|
|
3782
3781
|
configChain = Promise.resolve();
|
|
3783
3782
|
configAcks = /* @__PURE__ */ new Map();
|
|
@@ -3941,8 +3940,15 @@ var BppTransport = class {
|
|
|
3941
3940
|
}
|
|
3942
3941
|
});
|
|
3943
3942
|
ws.on("close", (code, reason) => {
|
|
3943
|
+
const closeReason = reason?.toString("utf8") ?? "";
|
|
3944
3944
|
connectionAbort.abort();
|
|
3945
3945
|
const wasCurrent = this.ws === ws;
|
|
3946
|
+
const closeSummary = `code=${code} reason=${closeReason || "<none>"} current=${wasCurrent}`;
|
|
3947
|
+
if (code === 1e3 || this.closed) {
|
|
3948
|
+
this.logger?.info("bpp.ws_closed", closeSummary);
|
|
3949
|
+
} else {
|
|
3950
|
+
this.logger?.warn("bpp.ws_closed", closeSummary);
|
|
3951
|
+
}
|
|
3946
3952
|
if (wasCurrent) {
|
|
3947
3953
|
this.online = false;
|
|
3948
3954
|
this.stopHeartbeat();
|
|
@@ -3952,7 +3958,7 @@ var BppTransport = class {
|
|
|
3952
3958
|
if (authFailed && wasCurrent) {
|
|
3953
3959
|
this.closed = true;
|
|
3954
3960
|
this.terminal = true;
|
|
3955
|
-
this.logger?.error("bpp.auth_failed", `server closed with ${WS_CLOSE_AUTH_FAILED} (authentication failed); not reconnecting. reason=${
|
|
3961
|
+
this.logger?.error("bpp.auth_failed", `server closed with ${WS_CLOSE_AUTH_FAILED} (authentication failed); not reconnecting. reason=${closeReason}`);
|
|
3956
3962
|
this.handlers?.onStateChange({ status: "error", reason: "api_key_invalid" });
|
|
3957
3963
|
}
|
|
3958
3964
|
if (wasCurrent) {
|
|
@@ -3998,6 +4004,7 @@ var BppTransport = class {
|
|
|
3998
4004
|
}
|
|
3999
4005
|
this.startHeartbeat();
|
|
4000
4006
|
this.goOnline(ws);
|
|
4007
|
+
this.logger?.info("bpp.connected");
|
|
4001
4008
|
resolve();
|
|
4002
4009
|
} catch (error) {
|
|
4003
4010
|
const failure = error instanceof BorgeeError ? error : new BorgeeError(`agent identity handshake failed: ${String(error)}`, "bpp.identity_unresolved");
|
|
@@ -4011,6 +4018,7 @@ var BppTransport = class {
|
|
|
4011
4018
|
this.reconnectAttempt += 1;
|
|
4012
4019
|
const delay = Math.min(this.reconnectBaseMs * 2 ** (this.reconnectAttempt - 1), this.reconnectMaxMs);
|
|
4013
4020
|
this.handlers?.onStateChange({ status: "reconnecting", attempt: this.reconnectAttempt });
|
|
4021
|
+
this.logger?.info("bpp.reconnect_scheduled", `attempt=${this.reconnectAttempt} delay_ms=${delay}`);
|
|
4014
4022
|
this.reconnectTimer = setTimeout(() => {
|
|
4015
4023
|
this.reconnectTimer = void 0;
|
|
4016
4024
|
if (this.closed)
|
|
@@ -4080,12 +4088,11 @@ var BppTransport = class {
|
|
|
4080
4088
|
}
|
|
4081
4089
|
handleInbound(frame) {
|
|
4082
4090
|
this.inboundChain = this.inboundChain.then(() => {
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
this.failTerminal(this.inboundFailure(error), this.ws);
|
|
4091
|
+
try {
|
|
4092
|
+
this.handlers?.onInbound(mapInbound(frame));
|
|
4093
|
+
} catch (error) {
|
|
4094
|
+
this.logger?.error("bpp.inbound_dispatch_failed", this.inboundFailure(error));
|
|
4095
|
+
}
|
|
4089
4096
|
});
|
|
4090
4097
|
}
|
|
4091
4098
|
handleActionResult(frame) {
|
|
@@ -4380,6 +4387,7 @@ var BppTransport = class {
|
|
|
4380
4387
|
failTerminal(error, ws) {
|
|
4381
4388
|
if (this.terminal)
|
|
4382
4389
|
return;
|
|
4390
|
+
this.logger?.error("bpp.terminal_failure", error);
|
|
4383
4391
|
this.terminal = true;
|
|
4384
4392
|
this.online = false;
|
|
4385
4393
|
this.handlers?.onStateChange({ status: "error", reason: "unknown", code: error.code });
|
|
@@ -5051,8 +5059,13 @@ var Client = class {
|
|
|
5051
5059
|
this.t.setStopTurnHandler?.(handler);
|
|
5052
5060
|
}
|
|
5053
5061
|
emit(event, payload) {
|
|
5054
|
-
for (const h of this.listeners[event])
|
|
5055
|
-
|
|
5062
|
+
for (const h of this.listeners[event]) {
|
|
5063
|
+
try {
|
|
5064
|
+
h(payload);
|
|
5065
|
+
} catch (error) {
|
|
5066
|
+
this.logger.error("client.observer_failed", { event, error });
|
|
5067
|
+
}
|
|
5068
|
+
}
|
|
5056
5069
|
}
|
|
5057
5070
|
handlers() {
|
|
5058
5071
|
return {
|