@band-ai/sdk 0.2.0 → 0.2.1
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/adapters.cjs +143 -61
- package/dist/adapters.d.cts +15 -2
- package/dist/adapters.d.ts +15 -2
- package/dist/adapters.js +103 -21
- package/package.json +1 -1
package/dist/adapters.cjs
CHANGED
|
@@ -30,6 +30,38 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
+
// src/core/errors.ts
|
|
34
|
+
var BandSdkError, UnsupportedFeatureError, ValidationError, RuntimeStateError;
|
|
35
|
+
var init_errors = __esm({
|
|
36
|
+
"src/core/errors.ts"() {
|
|
37
|
+
"use strict";
|
|
38
|
+
BandSdkError = class extends Error {
|
|
39
|
+
constructor(message, cause) {
|
|
40
|
+
super(message, cause !== void 0 ? { cause } : void 0);
|
|
41
|
+
this.name = "BandSdkError";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
UnsupportedFeatureError = class extends BandSdkError {
|
|
45
|
+
constructor(message) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = "UnsupportedFeatureError";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
ValidationError = class extends BandSdkError {
|
|
51
|
+
constructor(message, cause) {
|
|
52
|
+
super(message, cause);
|
|
53
|
+
this.name = "ValidationError";
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
RuntimeStateError = class extends BandSdkError {
|
|
57
|
+
constructor(message) {
|
|
58
|
+
super(message);
|
|
59
|
+
this.name = "RuntimeStateError";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
33
65
|
// src/contracts/memory.ts
|
|
34
66
|
function namedValues(values) {
|
|
35
67
|
return Object.fromEntries(values.map((value) => [value, value]));
|
|
@@ -108,38 +140,6 @@ var init_memory = __esm({
|
|
|
108
140
|
}
|
|
109
141
|
});
|
|
110
142
|
|
|
111
|
-
// src/core/errors.ts
|
|
112
|
-
var BandSdkError, UnsupportedFeatureError, ValidationError, RuntimeStateError;
|
|
113
|
-
var init_errors = __esm({
|
|
114
|
-
"src/core/errors.ts"() {
|
|
115
|
-
"use strict";
|
|
116
|
-
BandSdkError = class extends Error {
|
|
117
|
-
constructor(message, cause) {
|
|
118
|
-
super(message, cause !== void 0 ? { cause } : void 0);
|
|
119
|
-
this.name = "BandSdkError";
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
UnsupportedFeatureError = class extends BandSdkError {
|
|
123
|
-
constructor(message) {
|
|
124
|
-
super(message);
|
|
125
|
-
this.name = "UnsupportedFeatureError";
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
ValidationError = class extends BandSdkError {
|
|
129
|
-
constructor(message, cause) {
|
|
130
|
-
super(message, cause);
|
|
131
|
-
this.name = "ValidationError";
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
RuntimeStateError = class extends BandSdkError {
|
|
135
|
-
constructor(message) {
|
|
136
|
-
super(message);
|
|
137
|
-
this.name = "RuntimeStateError";
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
143
|
// src/contracts/chatEvents.ts
|
|
144
144
|
var CHAT_EVENT_TYPES, CHAT_MESSAGE_TYPES;
|
|
145
145
|
var init_chatEvents = __esm({
|
|
@@ -1066,6 +1066,18 @@ var ACPClientHistoryConverter = class {
|
|
|
1066
1066
|
}
|
|
1067
1067
|
};
|
|
1068
1068
|
|
|
1069
|
+
// src/core/logger.ts
|
|
1070
|
+
var noop = () => void 0;
|
|
1071
|
+
var NoopLogger = class {
|
|
1072
|
+
debug = noop;
|
|
1073
|
+
info = noop;
|
|
1074
|
+
warn = noop;
|
|
1075
|
+
error = noop;
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
// src/adapters/acp/ACPClientAdapter.ts
|
|
1079
|
+
init_errors();
|
|
1080
|
+
|
|
1069
1081
|
// src/runtime/prompts/base.ts
|
|
1070
1082
|
var ENVIRONMENT_SECTION = `
|
|
1071
1083
|
## Environment
|
|
@@ -2016,6 +2028,7 @@ var acpModule = new LazyAsyncValue({
|
|
|
2016
2028
|
});
|
|
2017
2029
|
|
|
2018
2030
|
// src/adapters/acp/ACPClientAdapter.ts
|
|
2031
|
+
var DEFAULT_PERMISSION_TIMEOUT_MS = 5 * 6e4;
|
|
2019
2032
|
var ACPClientAdapter = class extends SimpleAdapter {
|
|
2020
2033
|
command;
|
|
2021
2034
|
cwd;
|
|
@@ -2031,6 +2044,10 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
2031
2044
|
roomTools = /* @__PURE__ */ new Map();
|
|
2032
2045
|
activeSessions = /* @__PURE__ */ new Set();
|
|
2033
2046
|
bootstrappedSessions = /* @__PURE__ */ new Set();
|
|
2047
|
+
pendingPermissions = /* @__PURE__ */ new Map();
|
|
2048
|
+
resolvePermission;
|
|
2049
|
+
permissionTimeoutMs;
|
|
2050
|
+
logger;
|
|
2034
2051
|
backend = null;
|
|
2035
2052
|
backendPromise = null;
|
|
2036
2053
|
client = null;
|
|
@@ -2057,6 +2074,12 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
2057
2074
|
this.additionalMcpTools = [...options.additionalMcpTools ?? []];
|
|
2058
2075
|
this.clientCapabilities = options.clientCapabilities;
|
|
2059
2076
|
this.connectionFactory = options.connectionFactory ?? createSubprocessConnection;
|
|
2077
|
+
this.resolvePermission = options.resolvePermission;
|
|
2078
|
+
this.logger = options.logger ?? new NoopLogger();
|
|
2079
|
+
this.permissionTimeoutMs = options.permissionTimeoutMs ?? DEFAULT_PERMISSION_TIMEOUT_MS;
|
|
2080
|
+
if (this.resolvePermission && (!Number.isFinite(this.permissionTimeoutMs) || this.permissionTimeoutMs <= 0)) {
|
|
2081
|
+
throw new ValidationError(`permissionTimeoutMs must be a positive finite number, got ${options.permissionTimeoutMs}`);
|
|
2082
|
+
}
|
|
2060
2083
|
}
|
|
2061
2084
|
async onStarted(agentName, agentDescription) {
|
|
2062
2085
|
await super.onStarted(agentName, agentDescription);
|
|
@@ -2122,6 +2145,7 @@ ${message.content}`;
|
|
|
2122
2145
|
this.activeSessions.delete(sessionId);
|
|
2123
2146
|
this.bootstrappedSessions.delete(sessionId);
|
|
2124
2147
|
this.client?.setPermissionHandler(sessionId, void 0);
|
|
2148
|
+
this.cancelPendingPermissions(sessionId);
|
|
2125
2149
|
}
|
|
2126
2150
|
}
|
|
2127
2151
|
async onRuntimeStop() {
|
|
@@ -2134,6 +2158,7 @@ ${message.content}`;
|
|
|
2134
2158
|
this.bootstrappedSessions.clear();
|
|
2135
2159
|
this.roomToSession.clear();
|
|
2136
2160
|
this.roomTools.clear();
|
|
2161
|
+
this.cancelAllPendingPermissions();
|
|
2137
2162
|
this.client = null;
|
|
2138
2163
|
this.connection = null;
|
|
2139
2164
|
if (this.backend) {
|
|
@@ -2356,28 +2381,94 @@ ${message.content}`;
|
|
|
2356
2381
|
].join("\n");
|
|
2357
2382
|
}
|
|
2358
2383
|
async handlePermissionRequest(tools, roomId, params) {
|
|
2359
|
-
const selected = choosePermissionOption(params.options);
|
|
2360
2384
|
const toolName = params.toolCall.title ?? "unknown";
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2385
|
+
const autoSelection = this.resolvePermission ? void 0 : choosePermissionOption(params.options);
|
|
2386
|
+
const controller = this.resolvePermission ? new AbortController() : void 0;
|
|
2387
|
+
if (controller) {
|
|
2388
|
+
this.trackPending(params.sessionId, controller);
|
|
2389
|
+
}
|
|
2390
|
+
const [, chosenId] = await Promise.all([
|
|
2391
|
+
// This is the room's only "a permission request is pending" signal,
|
|
2392
|
+
// and the only one other room participants ever see — started
|
|
2393
|
+
// immediately rather than serialized in front of a manual wait that
|
|
2394
|
+
// can take up to `permissionTimeoutMs`.
|
|
2395
|
+
tools.sendEvent(`Permission requested: ${toolName}`, "tool_call", {
|
|
2396
|
+
permission_request: true,
|
|
2397
|
+
tool_name: toolName,
|
|
2398
|
+
tool_call_id: params.toolCall.toolCallId,
|
|
2399
|
+
acp_session_id: params.sessionId,
|
|
2400
|
+
auto_allowed: autoSelection !== void 0 && autoSelection !== null
|
|
2401
|
+
}),
|
|
2402
|
+
controller ? this.resolveManually(params.sessionId, params, controller) : Promise.resolve(autoSelection?.optionId)
|
|
2403
|
+
]);
|
|
2404
|
+
return this.toResponse(chosenId, params.options);
|
|
2405
|
+
}
|
|
2406
|
+
// `undefined`, or an id absent from this request's own `options` (a buggy
|
|
2407
|
+
// or stale caller), both map to `cancelled` — never silently treated as a
|
|
2408
|
+
// deny. A real match, reject-kind options included, maps to `selected`.
|
|
2409
|
+
toResponse(chosenId, options) {
|
|
2410
|
+
const matched = chosenId !== void 0 && options.some((option) => option.optionId === chosenId);
|
|
2411
|
+
return matched ? { outcome: { outcome: "selected", optionId: chosenId } } : { outcome: { outcome: "cancelled" } };
|
|
2412
|
+
}
|
|
2413
|
+
// Races the caller-supplied resolver against a timeout and against
|
|
2414
|
+
// `controller`'s own abort signal — aborted externally by
|
|
2415
|
+
// `cancelPendingPermissions`/`cancelAllPendingPermissions` (fired from
|
|
2416
|
+
// `onCleanup`/`stop()` below) when a room or the whole adapter tears down
|
|
2417
|
+
// while this is still pending. `controller` is the same object tracked in
|
|
2418
|
+
// `pendingPermissions` by the caller, so there is exactly one cancellation
|
|
2419
|
+
// channel here, not a second hand-rolled one alongside it.
|
|
2420
|
+
async resolveManually(sessionId, params, controller) {
|
|
2421
|
+
let timer;
|
|
2422
|
+
const cancelled = new Promise((resolve) => {
|
|
2423
|
+
controller.signal.addEventListener("abort", () => resolve(void 0));
|
|
2424
|
+
});
|
|
2425
|
+
try {
|
|
2426
|
+
const timeout = new Promise((resolve) => {
|
|
2427
|
+
timer = setTimeout(() => resolve(void 0), this.permissionTimeoutMs);
|
|
2428
|
+
});
|
|
2429
|
+
return await Promise.race([
|
|
2430
|
+
// `resolvePermission` is caller-supplied; nothing guarantees it's
|
|
2431
|
+
// `async` or otherwise well-behaved. `Promise.resolve().then(...)`
|
|
2432
|
+
// normalizes a synchronous throw the same way it normalizes a
|
|
2433
|
+
// rejected promise, so both land in the `.catch` below rather than
|
|
2434
|
+
// escaping this race uncaught.
|
|
2435
|
+
Promise.resolve().then(() => this.resolvePermission(params, controller.signal)).catch((error) => {
|
|
2436
|
+
try {
|
|
2437
|
+
this.logger.warn("resolvePermission threw; treating as no answer", { error: String(error) });
|
|
2438
|
+
} catch {
|
|
2439
|
+
}
|
|
2440
|
+
return void 0;
|
|
2441
|
+
}),
|
|
2442
|
+
timeout,
|
|
2443
|
+
cancelled
|
|
2444
|
+
]);
|
|
2445
|
+
} finally {
|
|
2446
|
+
clearTimeout(timer);
|
|
2447
|
+
this.untrackPending(sessionId, controller);
|
|
2448
|
+
controller.abort();
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
trackPending(sessionId, controller) {
|
|
2452
|
+
const pending = this.pendingPermissions.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
2453
|
+
pending.add(controller);
|
|
2454
|
+
this.pendingPermissions.set(sessionId, pending);
|
|
2455
|
+
}
|
|
2456
|
+
untrackPending(sessionId, controller) {
|
|
2457
|
+
const pending = this.pendingPermissions.get(sessionId);
|
|
2458
|
+
pending?.delete(controller);
|
|
2459
|
+
if (pending?.size === 0) {
|
|
2460
|
+
this.pendingPermissions.delete(sessionId);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
cancelPendingPermissions(sessionId) {
|
|
2464
|
+
for (const controller of this.pendingPermissions.get(sessionId) ?? []) {
|
|
2465
|
+
controller.abort();
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
cancelAllPendingPermissions() {
|
|
2469
|
+
for (const sessionId of this.pendingPermissions.keys()) {
|
|
2470
|
+
this.cancelPendingPermissions(sessionId);
|
|
2374
2471
|
}
|
|
2375
|
-
return {
|
|
2376
|
-
outcome: {
|
|
2377
|
-
outcome: "selected",
|
|
2378
|
-
optionId: selected.optionId
|
|
2379
|
-
}
|
|
2380
|
-
};
|
|
2381
2472
|
}
|
|
2382
2473
|
async flushChunks(input) {
|
|
2383
2474
|
const client = this.client;
|
|
@@ -3345,15 +3436,6 @@ function extractPromptText(prompt) {
|
|
|
3345
3436
|
// src/adapters/tool-calling/ToolCallingAdapter.ts
|
|
3346
3437
|
init_protocols();
|
|
3347
3438
|
|
|
3348
|
-
// src/core/logger.ts
|
|
3349
|
-
var noop = () => void 0;
|
|
3350
|
-
var NoopLogger = class {
|
|
3351
|
-
debug = noop;
|
|
3352
|
-
info = noop;
|
|
3353
|
-
warn = noop;
|
|
3354
|
-
error = noop;
|
|
3355
|
-
};
|
|
3356
|
-
|
|
3357
3439
|
// src/runtime/formatters.ts
|
|
3358
3440
|
function isMetadataMap(value) {
|
|
3359
3441
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
package/dist/adapters.d.cts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export { A as A2AAdapter, a as A2AAdapterOptions, K as A2AClientFactory, M as A2AClientLike, b as A2AGatewayAdapter, c as AnthropicAdapter, d as AnthropicAdapterOptions, N as AnthropicClientFactory, Q as AnthropicToolCallingModel, R as AnthropicToolCallingModelOptions, C as CODEX_REASONING_EFFORTS, e as CODEX_REASONING_SUMMARIES, f as CODEX_WEB_SEARCH_MODES, g as ClaudePermissionMode, h as ClaudeSDKAdapter, i as ClaudeSDKAdapterOptions, S as ClaudeSDKQuery, U as ClaudeSDKQueryParams, j as CodexAdapter, k as CodexAdapterConfig, W as CodexAppServerStdioClient, l as CodexApprovalPolicy, X as CodexClientLike, Y as CodexJsonRpcError, m as CodexReasoningEffort, n as CodexReasoningSummary, o as CodexSandboxMode, p as CodexWebSearchMode, Z as DynamicToolCallParams, _ as DynamicToolCallResponse, $ as DynamicToolSpec, G as GeminiAdapter, q as GeminiAdapterOptions, a0 as GeminiClientFactory, a1 as GeminiToolCallingModel, a2 as GeminiToolCallingModelOptions, r as GenericAdapter, s as GenericAdapterHandler, t as GoogleADKAdapter, u as GoogleADKAdapterOptions, a3 as HttpOpencodeClient, a4 as HttpOpencodeClientOptions, a5 as HttpStatusError, L as LangGraphAdapter, v as LangGraphAdapterOptions, w as LangGraphGraph, x as LettaAdapter, y as LettaAdapterOptions, a6 as LettaAgentCreateParams, a7 as LettaClientFactory, a8 as LettaClientLike, a9 as LettaHistoryConverter, aa as LettaMessage, ab as LettaMessageCreateParams, ac as LettaMessages, ad as LettaRequestOptions, ae as LettaResponse, af as LettaResponseMessage, O as OpenAIAdapter, z as OpenAIAdapterOptions, ag as OpenAIClientFactory, ah as OpenAIToolCallingModel, ai as OpenAIToolCallingModelOptions, B as OpencodeAdapter, D as OpencodeAdapterConfig, E as OpencodeApprovalMode, F as OpencodeApprovalReply, aj as OpencodeClientLike, H as OpencodeQuestionMode, P as ParlantAdapter, I as ParlantAdapterOptions, ak as ParlantClientFactory, al as ParlantClientLike, am as ToolCall, an as ToolCallingAdapter, ao as ToolCallingAdapterOptions, T as ToolCallingModel, ap as ToolCallingModelRequest, aq as ToolCallingResponse, ar as ToolResult, as as TurnStartParams, V as VercelAISDKAdapter, J as VercelAISDKAdapterOptions, at as VercelAISDKToolCallingModel, au as VercelAISDKToolCallingModelOptions, av as runSingleToolRound } from './ClaudeSDKAdapter-BY4zEbCl.cjs';
|
|
2
2
|
import * as _agentclientprotocol_sdk from '@agentclientprotocol/sdk';
|
|
3
|
-
import { Client, ClientSideConnection, McpServer, ClientCapabilities, SessionMode, AgentSideConnection, SessionModeState, Agent, InitializeResponse, Implementation, Stream, InitializeRequest, LoadSessionRequest, LoadSessionResponse, ListSessionsRequest, ListSessionsResponse, ForkSessionRequest, ForkSessionResponse, ResumeSessionRequest, ResumeSessionResponse, SetSessionModeRequest, SetSessionModeResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, AuthenticateRequest, AuthenticateResponse, PromptRequest, PromptResponse } from '@agentclientprotocol/sdk';
|
|
3
|
+
import { Client, ClientSideConnection, McpServer, ClientCapabilities, RequestPermissionRequest, SessionMode, AgentSideConnection, SessionModeState, Agent, InitializeResponse, Implementation, Stream, InitializeRequest, LoadSessionRequest, LoadSessionResponse, ListSessionsRequest, ListSessionsResponse, ForkSessionRequest, ForkSessionResponse, ResumeSessionRequest, ResumeSessionResponse, SetSessionModeRequest, SetSessionModeResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, AuthenticateRequest, AuthenticateResponse, PromptRequest, PromptResponse } from '@agentclientprotocol/sdk';
|
|
4
4
|
import { A as ACPClientSessionState, a as ACPServerSessionState } from './acp-server-Dlj7D563.cjs';
|
|
5
5
|
export { G as GatewayHistoryConverter } from './acp-server-Dlj7D563.cjs';
|
|
6
6
|
import { S as SimpleAdapter } from './simpleAdapter-BpT4XbZC.cjs';
|
|
7
|
+
import { L as Logger } from './logger-CABQOnlR.cjs';
|
|
7
8
|
import { A as AdapterToolsProtocol, c as MessagingTools } from './protocols-Bz1rxcUg.cjs';
|
|
8
9
|
import { P as PlatformMessage } from './types-D958TC71.cjs';
|
|
9
10
|
import { M as McpToolRegistration } from './sdk-BTciSLRQ.cjs';
|
|
10
11
|
import { R as RestApi } from './types-BgYFd_Yw.cjs';
|
|
11
12
|
import { b as GatewayServerLike, c as GatewayServerOptions } from './opencode-2YdscIc1.cjs';
|
|
12
13
|
export { A as A2AAuth, a as A2AGatewayAdapterOptions, d as A2AHistoryConverter, e as A2ASessionState, f as GatewayA2AMessage, g as GatewayA2AStatusUpdateEvent, h as GatewayCancelRequest, i as GatewayPeer, j as GatewayRequest, k as GatewayServerFactory, G as GatewaySessionState, l as GatewayTaskState, P as ParlantHistoryConverter, m as ParlantMessage, n as ParlantMessages, o as PendingA2ATask, p as buildA2AAuthHeaders } from './opencode-2YdscIc1.cjs';
|
|
13
|
-
import './logger-CABQOnlR.cjs';
|
|
14
14
|
import './customTools-BzF0IISO.cjs';
|
|
15
15
|
import 'zod';
|
|
16
16
|
import './dtos-B8KU_q4d.cjs';
|
|
@@ -52,6 +52,9 @@ interface ACPClientAdapterOptions {
|
|
|
52
52
|
additionalMcpTools?: McpToolRegistration[];
|
|
53
53
|
clientCapabilities?: ClientCapabilities;
|
|
54
54
|
connectionFactory?: ACPClientConnectionFactory;
|
|
55
|
+
resolvePermission?: (request: RequestPermissionRequest, signal: AbortSignal) => Promise<string | undefined>;
|
|
56
|
+
permissionTimeoutMs?: number;
|
|
57
|
+
logger?: Logger;
|
|
55
58
|
}
|
|
56
59
|
declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, AdapterToolsProtocol> {
|
|
57
60
|
private readonly command;
|
|
@@ -68,6 +71,10 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
|
|
|
68
71
|
private readonly roomTools;
|
|
69
72
|
private readonly activeSessions;
|
|
70
73
|
private readonly bootstrappedSessions;
|
|
74
|
+
private readonly pendingPermissions;
|
|
75
|
+
private readonly resolvePermission?;
|
|
76
|
+
private readonly permissionTimeoutMs;
|
|
77
|
+
private readonly logger;
|
|
71
78
|
private backend;
|
|
72
79
|
private backendPromise;
|
|
73
80
|
private client;
|
|
@@ -96,6 +103,12 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
|
|
|
96
103
|
private createBackend;
|
|
97
104
|
private buildSystemContext;
|
|
98
105
|
private handlePermissionRequest;
|
|
106
|
+
private toResponse;
|
|
107
|
+
private resolveManually;
|
|
108
|
+
private trackPending;
|
|
109
|
+
private untrackPending;
|
|
110
|
+
private cancelPendingPermissions;
|
|
111
|
+
private cancelAllPendingPermissions;
|
|
99
112
|
private flushChunks;
|
|
100
113
|
}
|
|
101
114
|
|
package/dist/adapters.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export { A as A2AAdapter, a as A2AAdapterOptions, K as A2AClientFactory, M as A2AClientLike, b as A2AGatewayAdapter, c as AnthropicAdapter, d as AnthropicAdapterOptions, N as AnthropicClientFactory, Q as AnthropicToolCallingModel, R as AnthropicToolCallingModelOptions, C as CODEX_REASONING_EFFORTS, e as CODEX_REASONING_SUMMARIES, f as CODEX_WEB_SEARCH_MODES, g as ClaudePermissionMode, h as ClaudeSDKAdapter, i as ClaudeSDKAdapterOptions, S as ClaudeSDKQuery, U as ClaudeSDKQueryParams, j as CodexAdapter, k as CodexAdapterConfig, W as CodexAppServerStdioClient, l as CodexApprovalPolicy, X as CodexClientLike, Y as CodexJsonRpcError, m as CodexReasoningEffort, n as CodexReasoningSummary, o as CodexSandboxMode, p as CodexWebSearchMode, Z as DynamicToolCallParams, _ as DynamicToolCallResponse, $ as DynamicToolSpec, G as GeminiAdapter, q as GeminiAdapterOptions, a0 as GeminiClientFactory, a1 as GeminiToolCallingModel, a2 as GeminiToolCallingModelOptions, r as GenericAdapter, s as GenericAdapterHandler, t as GoogleADKAdapter, u as GoogleADKAdapterOptions, a3 as HttpOpencodeClient, a4 as HttpOpencodeClientOptions, a5 as HttpStatusError, L as LangGraphAdapter, v as LangGraphAdapterOptions, w as LangGraphGraph, x as LettaAdapter, y as LettaAdapterOptions, a6 as LettaAgentCreateParams, a7 as LettaClientFactory, a8 as LettaClientLike, a9 as LettaHistoryConverter, aa as LettaMessage, ab as LettaMessageCreateParams, ac as LettaMessages, ad as LettaRequestOptions, ae as LettaResponse, af as LettaResponseMessage, O as OpenAIAdapter, z as OpenAIAdapterOptions, ag as OpenAIClientFactory, ah as OpenAIToolCallingModel, ai as OpenAIToolCallingModelOptions, B as OpencodeAdapter, D as OpencodeAdapterConfig, E as OpencodeApprovalMode, F as OpencodeApprovalReply, aj as OpencodeClientLike, H as OpencodeQuestionMode, P as ParlantAdapter, I as ParlantAdapterOptions, ak as ParlantClientFactory, al as ParlantClientLike, am as ToolCall, an as ToolCallingAdapter, ao as ToolCallingAdapterOptions, T as ToolCallingModel, ap as ToolCallingModelRequest, aq as ToolCallingResponse, ar as ToolResult, as as TurnStartParams, V as VercelAISDKAdapter, J as VercelAISDKAdapterOptions, at as VercelAISDKToolCallingModel, au as VercelAISDKToolCallingModelOptions, av as runSingleToolRound } from './ClaudeSDKAdapter-Cna5P1dR.js';
|
|
2
2
|
import * as _agentclientprotocol_sdk from '@agentclientprotocol/sdk';
|
|
3
|
-
import { Client, ClientSideConnection, McpServer, ClientCapabilities, SessionMode, AgentSideConnection, SessionModeState, Agent, InitializeResponse, Implementation, Stream, InitializeRequest, LoadSessionRequest, LoadSessionResponse, ListSessionsRequest, ListSessionsResponse, ForkSessionRequest, ForkSessionResponse, ResumeSessionRequest, ResumeSessionResponse, SetSessionModeRequest, SetSessionModeResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, AuthenticateRequest, AuthenticateResponse, PromptRequest, PromptResponse } from '@agentclientprotocol/sdk';
|
|
3
|
+
import { Client, ClientSideConnection, McpServer, ClientCapabilities, RequestPermissionRequest, SessionMode, AgentSideConnection, SessionModeState, Agent, InitializeResponse, Implementation, Stream, InitializeRequest, LoadSessionRequest, LoadSessionResponse, ListSessionsRequest, ListSessionsResponse, ForkSessionRequest, ForkSessionResponse, ResumeSessionRequest, ResumeSessionResponse, SetSessionModeRequest, SetSessionModeResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, AuthenticateRequest, AuthenticateResponse, PromptRequest, PromptResponse } from '@agentclientprotocol/sdk';
|
|
4
4
|
import { A as ACPClientSessionState, a as ACPServerSessionState } from './acp-server-CiUqN3G3.js';
|
|
5
5
|
export { G as GatewayHistoryConverter } from './acp-server-CiUqN3G3.js';
|
|
6
6
|
import { S as SimpleAdapter } from './simpleAdapter--wznuoOw.js';
|
|
7
|
+
import { L as Logger } from './logger-CABQOnlR.js';
|
|
7
8
|
import { A as AdapterToolsProtocol, c as MessagingTools } from './protocols-Bwwcql0h.js';
|
|
8
9
|
import { P as PlatformMessage } from './types-BTN_ZETM.js';
|
|
9
10
|
import { M as McpToolRegistration } from './sdk-qKJtMma_.js';
|
|
10
11
|
import { R as RestApi } from './types-BivGO7I9.js';
|
|
11
12
|
import { b as GatewayServerLike, c as GatewayServerOptions } from './opencode-Bld62x5t.js';
|
|
12
13
|
export { A as A2AAuth, a as A2AGatewayAdapterOptions, d as A2AHistoryConverter, e as A2ASessionState, f as GatewayA2AMessage, g as GatewayA2AStatusUpdateEvent, h as GatewayCancelRequest, i as GatewayPeer, j as GatewayRequest, k as GatewayServerFactory, G as GatewaySessionState, l as GatewayTaskState, P as ParlantHistoryConverter, m as ParlantMessage, n as ParlantMessages, o as PendingA2ATask, p as buildA2AAuthHeaders } from './opencode-Bld62x5t.js';
|
|
13
|
-
import './logger-CABQOnlR.js';
|
|
14
14
|
import './customTools-BzF0IISO.js';
|
|
15
15
|
import 'zod';
|
|
16
16
|
import './dtos-B8KU_q4d.js';
|
|
@@ -52,6 +52,9 @@ interface ACPClientAdapterOptions {
|
|
|
52
52
|
additionalMcpTools?: McpToolRegistration[];
|
|
53
53
|
clientCapabilities?: ClientCapabilities;
|
|
54
54
|
connectionFactory?: ACPClientConnectionFactory;
|
|
55
|
+
resolvePermission?: (request: RequestPermissionRequest, signal: AbortSignal) => Promise<string | undefined>;
|
|
56
|
+
permissionTimeoutMs?: number;
|
|
57
|
+
logger?: Logger;
|
|
55
58
|
}
|
|
56
59
|
declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, AdapterToolsProtocol> {
|
|
57
60
|
private readonly command;
|
|
@@ -68,6 +71,10 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
|
|
|
68
71
|
private readonly roomTools;
|
|
69
72
|
private readonly activeSessions;
|
|
70
73
|
private readonly bootstrappedSessions;
|
|
74
|
+
private readonly pendingPermissions;
|
|
75
|
+
private readonly resolvePermission?;
|
|
76
|
+
private readonly permissionTimeoutMs;
|
|
77
|
+
private readonly logger;
|
|
71
78
|
private backend;
|
|
72
79
|
private backendPromise;
|
|
73
80
|
private client;
|
|
@@ -96,6 +103,12 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
|
|
|
96
103
|
private createBackend;
|
|
97
104
|
private buildSystemContext;
|
|
98
105
|
private handlePermissionRequest;
|
|
106
|
+
private toResponse;
|
|
107
|
+
private resolveManually;
|
|
108
|
+
private trackPending;
|
|
109
|
+
private untrackPending;
|
|
110
|
+
private cancelPendingPermissions;
|
|
111
|
+
private cancelAllPendingPermissions;
|
|
99
112
|
private flushChunks;
|
|
100
113
|
}
|
|
101
114
|
|
package/dist/adapters.js
CHANGED
|
@@ -63,9 +63,12 @@ import {
|
|
|
63
63
|
} from "./chunk-RV76SKFT.js";
|
|
64
64
|
import "./chunk-ZZJRRBPQ.js";
|
|
65
65
|
import "./chunk-3BKAC4OZ.js";
|
|
66
|
-
import "./chunk-OD2G5LFQ.js";
|
|
67
66
|
import {
|
|
68
|
-
|
|
67
|
+
NoopLogger
|
|
68
|
+
} from "./chunk-OD2G5LFQ.js";
|
|
69
|
+
import {
|
|
70
|
+
UnsupportedFeatureError,
|
|
71
|
+
ValidationError
|
|
69
72
|
} from "./chunk-JY75VSQK.js";
|
|
70
73
|
|
|
71
74
|
// src/adapters/acp/ACPClientAdapter.ts
|
|
@@ -344,6 +347,7 @@ var acpModule = new LazyAsyncValue({
|
|
|
344
347
|
});
|
|
345
348
|
|
|
346
349
|
// src/adapters/acp/ACPClientAdapter.ts
|
|
350
|
+
var DEFAULT_PERMISSION_TIMEOUT_MS = 5 * 6e4;
|
|
347
351
|
var ACPClientAdapter = class extends SimpleAdapter {
|
|
348
352
|
command;
|
|
349
353
|
cwd;
|
|
@@ -359,6 +363,10 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
359
363
|
roomTools = /* @__PURE__ */ new Map();
|
|
360
364
|
activeSessions = /* @__PURE__ */ new Set();
|
|
361
365
|
bootstrappedSessions = /* @__PURE__ */ new Set();
|
|
366
|
+
pendingPermissions = /* @__PURE__ */ new Map();
|
|
367
|
+
resolvePermission;
|
|
368
|
+
permissionTimeoutMs;
|
|
369
|
+
logger;
|
|
362
370
|
backend = null;
|
|
363
371
|
backendPromise = null;
|
|
364
372
|
client = null;
|
|
@@ -385,6 +393,12 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
385
393
|
this.additionalMcpTools = [...options.additionalMcpTools ?? []];
|
|
386
394
|
this.clientCapabilities = options.clientCapabilities;
|
|
387
395
|
this.connectionFactory = options.connectionFactory ?? createSubprocessConnection;
|
|
396
|
+
this.resolvePermission = options.resolvePermission;
|
|
397
|
+
this.logger = options.logger ?? new NoopLogger();
|
|
398
|
+
this.permissionTimeoutMs = options.permissionTimeoutMs ?? DEFAULT_PERMISSION_TIMEOUT_MS;
|
|
399
|
+
if (this.resolvePermission && (!Number.isFinite(this.permissionTimeoutMs) || this.permissionTimeoutMs <= 0)) {
|
|
400
|
+
throw new ValidationError(`permissionTimeoutMs must be a positive finite number, got ${options.permissionTimeoutMs}`);
|
|
401
|
+
}
|
|
388
402
|
}
|
|
389
403
|
async onStarted(agentName, agentDescription) {
|
|
390
404
|
await super.onStarted(agentName, agentDescription);
|
|
@@ -450,6 +464,7 @@ ${message.content}`;
|
|
|
450
464
|
this.activeSessions.delete(sessionId);
|
|
451
465
|
this.bootstrappedSessions.delete(sessionId);
|
|
452
466
|
this.client?.setPermissionHandler(sessionId, void 0);
|
|
467
|
+
this.cancelPendingPermissions(sessionId);
|
|
453
468
|
}
|
|
454
469
|
}
|
|
455
470
|
async onRuntimeStop() {
|
|
@@ -462,6 +477,7 @@ ${message.content}`;
|
|
|
462
477
|
this.bootstrappedSessions.clear();
|
|
463
478
|
this.roomToSession.clear();
|
|
464
479
|
this.roomTools.clear();
|
|
480
|
+
this.cancelAllPendingPermissions();
|
|
465
481
|
this.client = null;
|
|
466
482
|
this.connection = null;
|
|
467
483
|
if (this.backend) {
|
|
@@ -684,28 +700,94 @@ ${message.content}`;
|
|
|
684
700
|
].join("\n");
|
|
685
701
|
}
|
|
686
702
|
async handlePermissionRequest(tools, roomId, params) {
|
|
687
|
-
const selected = choosePermissionOption(params.options);
|
|
688
703
|
const toolName = params.toolCall.title ?? "unknown";
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
704
|
+
const autoSelection = this.resolvePermission ? void 0 : choosePermissionOption(params.options);
|
|
705
|
+
const controller = this.resolvePermission ? new AbortController() : void 0;
|
|
706
|
+
if (controller) {
|
|
707
|
+
this.trackPending(params.sessionId, controller);
|
|
708
|
+
}
|
|
709
|
+
const [, chosenId] = await Promise.all([
|
|
710
|
+
// This is the room's only "a permission request is pending" signal,
|
|
711
|
+
// and the only one other room participants ever see — started
|
|
712
|
+
// immediately rather than serialized in front of a manual wait that
|
|
713
|
+
// can take up to `permissionTimeoutMs`.
|
|
714
|
+
tools.sendEvent(`Permission requested: ${toolName}`, "tool_call", {
|
|
715
|
+
permission_request: true,
|
|
716
|
+
tool_name: toolName,
|
|
717
|
+
tool_call_id: params.toolCall.toolCallId,
|
|
718
|
+
acp_session_id: params.sessionId,
|
|
719
|
+
auto_allowed: autoSelection !== void 0 && autoSelection !== null
|
|
720
|
+
}),
|
|
721
|
+
controller ? this.resolveManually(params.sessionId, params, controller) : Promise.resolve(autoSelection?.optionId)
|
|
722
|
+
]);
|
|
723
|
+
return this.toResponse(chosenId, params.options);
|
|
724
|
+
}
|
|
725
|
+
// `undefined`, or an id absent from this request's own `options` (a buggy
|
|
726
|
+
// or stale caller), both map to `cancelled` — never silently treated as a
|
|
727
|
+
// deny. A real match, reject-kind options included, maps to `selected`.
|
|
728
|
+
toResponse(chosenId, options) {
|
|
729
|
+
const matched = chosenId !== void 0 && options.some((option) => option.optionId === chosenId);
|
|
730
|
+
return matched ? { outcome: { outcome: "selected", optionId: chosenId } } : { outcome: { outcome: "cancelled" } };
|
|
731
|
+
}
|
|
732
|
+
// Races the caller-supplied resolver against a timeout and against
|
|
733
|
+
// `controller`'s own abort signal — aborted externally by
|
|
734
|
+
// `cancelPendingPermissions`/`cancelAllPendingPermissions` (fired from
|
|
735
|
+
// `onCleanup`/`stop()` below) when a room or the whole adapter tears down
|
|
736
|
+
// while this is still pending. `controller` is the same object tracked in
|
|
737
|
+
// `pendingPermissions` by the caller, so there is exactly one cancellation
|
|
738
|
+
// channel here, not a second hand-rolled one alongside it.
|
|
739
|
+
async resolveManually(sessionId, params, controller) {
|
|
740
|
+
let timer;
|
|
741
|
+
const cancelled = new Promise((resolve) => {
|
|
742
|
+
controller.signal.addEventListener("abort", () => resolve(void 0));
|
|
695
743
|
});
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
744
|
+
try {
|
|
745
|
+
const timeout = new Promise((resolve) => {
|
|
746
|
+
timer = setTimeout(() => resolve(void 0), this.permissionTimeoutMs);
|
|
747
|
+
});
|
|
748
|
+
return await Promise.race([
|
|
749
|
+
// `resolvePermission` is caller-supplied; nothing guarantees it's
|
|
750
|
+
// `async` or otherwise well-behaved. `Promise.resolve().then(...)`
|
|
751
|
+
// normalizes a synchronous throw the same way it normalizes a
|
|
752
|
+
// rejected promise, so both land in the `.catch` below rather than
|
|
753
|
+
// escaping this race uncaught.
|
|
754
|
+
Promise.resolve().then(() => this.resolvePermission(params, controller.signal)).catch((error) => {
|
|
755
|
+
try {
|
|
756
|
+
this.logger.warn("resolvePermission threw; treating as no answer", { error: String(error) });
|
|
757
|
+
} catch {
|
|
758
|
+
}
|
|
759
|
+
return void 0;
|
|
760
|
+
}),
|
|
761
|
+
timeout,
|
|
762
|
+
cancelled
|
|
763
|
+
]);
|
|
764
|
+
} finally {
|
|
765
|
+
clearTimeout(timer);
|
|
766
|
+
this.untrackPending(sessionId, controller);
|
|
767
|
+
controller.abort();
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
trackPending(sessionId, controller) {
|
|
771
|
+
const pending = this.pendingPermissions.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
772
|
+
pending.add(controller);
|
|
773
|
+
this.pendingPermissions.set(sessionId, pending);
|
|
774
|
+
}
|
|
775
|
+
untrackPending(sessionId, controller) {
|
|
776
|
+
const pending = this.pendingPermissions.get(sessionId);
|
|
777
|
+
pending?.delete(controller);
|
|
778
|
+
if (pending?.size === 0) {
|
|
779
|
+
this.pendingPermissions.delete(sessionId);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
cancelPendingPermissions(sessionId) {
|
|
783
|
+
for (const controller of this.pendingPermissions.get(sessionId) ?? []) {
|
|
784
|
+
controller.abort();
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
cancelAllPendingPermissions() {
|
|
788
|
+
for (const sessionId of this.pendingPermissions.keys()) {
|
|
789
|
+
this.cancelPendingPermissions(sessionId);
|
|
702
790
|
}
|
|
703
|
-
return {
|
|
704
|
-
outcome: {
|
|
705
|
-
outcome: "selected",
|
|
706
|
-
optionId: selected.optionId
|
|
707
|
-
}
|
|
708
|
-
};
|
|
709
791
|
}
|
|
710
792
|
async flushChunks(input) {
|
|
711
793
|
const client = this.client;
|