@agen-ai/acp-transport 0.4.3 → 0.4.4
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 +15 -1
- package/dist/client.js +4 -4
- package/dist/clientContracts.d.ts +11 -3
- package/dist/clientState.d.ts +3 -3
- package/dist/clientState.js +13 -4
- package/dist/standardSessionOperations.d.ts +11 -0
- package/dist/standardSessionOperations.js +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ slow output consumer does not block correlated responses or cancellation. Hosts
|
|
|
76
76
|
must reserve bounded queue capacity during handler admission and retain that
|
|
77
77
|
reservation until processing completes.
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
Finite request deadlines and bounded shutdown drains keep Node's event loop alive until
|
|
80
80
|
the operation settles, including when the supplied streams have no active I/O
|
|
81
81
|
handles. Settlement clears the operation's timer. Always await `client.dispose()`
|
|
82
82
|
when the connection is no longer needed to reject pending requests and complete
|
|
@@ -153,6 +153,20 @@ and output backpressure. Notification delivery alone does not provide a durable
|
|
|
153
153
|
event journal or a provider-neutral turn state machine.
|
|
154
154
|
|
|
155
155
|
Request cancellation or timeout does not prove that the peer stopped execution.
|
|
156
|
+
Requests default to bounded waiting, using the configured finite timeout and the
|
|
157
|
+
earlier optional `deadlineAt`. Existing numeric `timeoutMs` and `deadlineAt` calls
|
|
158
|
+
retain those limits. `lifetime: 'bounded'` makes that default explicit.
|
|
159
|
+
|
|
160
|
+
Select `{ lifetime: 'until_settled' }` for an execution request that must retain
|
|
161
|
+
its original RPC waiter until a response, explicit abort, disposal or connection
|
|
162
|
+
failure. This choice schedules no request timer and cannot be combined with
|
|
163
|
+
`timeoutMs` or `deadlineAt`, even when either property is explicitly `undefined`.
|
|
164
|
+
Contradictions reject before dispatch. The request still consumes bounded pending
|
|
165
|
+
capacity, retains its exact ID and response validation, and respects signals and
|
|
166
|
+
disposal. The caller must own cancellation, output consumption and cleanup. For a
|
|
167
|
+
long native operation, request abort alone does not establish native cancellation;
|
|
168
|
+
retain the RPC while performing the protocol's cancellation-confirmation flow.
|
|
169
|
+
|
|
156
170
|
`onRequestDispatch` receives the exact allocated `requestId` at the boundary immediately
|
|
157
171
|
before the first write, allowing request-scoped reverse traffic to be correlated before
|
|
158
172
|
the peer can respond. A callback that aborts or rejects admission prevents the request
|
package/dist/client.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./protocol.js";
|
|
12
12
|
import { createAcpSchemaValidator } from "./schema.js";
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
resolveRequestTimeout,
|
|
15
15
|
cleanupPendingRequest,
|
|
16
16
|
deferred,
|
|
17
17
|
isCriticalExtensionMethod
|
|
@@ -410,13 +410,13 @@ function createAcpClient(options) {
|
|
|
410
410
|
);
|
|
411
411
|
}
|
|
412
412
|
const extension = validateOutbound("request", method, params);
|
|
413
|
-
const timeoutMs =
|
|
413
|
+
const timeoutMs = resolveRequestTimeout({
|
|
414
414
|
options: requestOptions,
|
|
415
415
|
now: now(),
|
|
416
416
|
defaultMs: limits.defaultRequestTimeoutMs,
|
|
417
417
|
maximumMs: limits.maxRequestTimeoutMs
|
|
418
418
|
});
|
|
419
|
-
if (timeoutMs <= 0 || requestOptions.signal?.aborted) {
|
|
419
|
+
if (timeoutMs !== void 0 && timeoutMs <= 0 || requestOptions.signal?.aborted) {
|
|
420
420
|
throw new AcpRequestError("acp_request_aborted", 0);
|
|
421
421
|
}
|
|
422
422
|
const id = allocateRequestId();
|
|
@@ -430,7 +430,7 @@ function createAcpClient(options) {
|
|
|
430
430
|
sendCancellation(id);
|
|
431
431
|
};
|
|
432
432
|
requestOptions.signal?.addEventListener("abort", abort, { once: true });
|
|
433
|
-
const timer = setTimeout(() => {
|
|
433
|
+
const timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
|
|
434
434
|
const entry2 = pending.get(key);
|
|
435
435
|
if (!entry2) return;
|
|
436
436
|
cleanupPending(entry2);
|
|
@@ -47,15 +47,22 @@ export interface CreateAcpClientOptions {
|
|
|
47
47
|
readonly onFatalError?: (error: Error) => void;
|
|
48
48
|
readonly disposeTransport?: () => void | Promise<void>;
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
readonly timeoutMs?: number;
|
|
52
|
-
readonly deadlineAt?: number | Date;
|
|
50
|
+
interface AcpRequestContextOptions {
|
|
53
51
|
readonly signal?: AbortSignal;
|
|
54
52
|
/** Runs synchronously after local admission and immediately before the transport write. */
|
|
55
53
|
readonly onRequestDispatch?: (context: AcpRequestDispatchContext) => void;
|
|
56
54
|
/** Runs synchronously after response validation, before promise settlement and the next frame. */
|
|
57
55
|
readonly onResponseReceived?: (response: AcpResponseReceived) => void;
|
|
58
56
|
}
|
|
57
|
+
export type AcpRequestOptions = AcpRequestContextOptions & (Readonly<{
|
|
58
|
+
lifetime?: 'bounded';
|
|
59
|
+
timeoutMs?: number;
|
|
60
|
+
deadlineAt?: number | Date;
|
|
61
|
+
}> | Readonly<{
|
|
62
|
+
lifetime: 'until_settled';
|
|
63
|
+
timeoutMs?: never;
|
|
64
|
+
deadlineAt?: never;
|
|
65
|
+
}>);
|
|
59
66
|
export interface AcpClientCloseResult {
|
|
60
67
|
readonly kind: 'disposed' | 'peer_closed' | 'fatal';
|
|
61
68
|
readonly error?: Error;
|
|
@@ -67,4 +74,5 @@ export interface AcpClient {
|
|
|
67
74
|
readonly closed: Promise<AcpClientCloseResult>;
|
|
68
75
|
readonly dispose: () => Promise<void>;
|
|
69
76
|
}
|
|
77
|
+
export {};
|
|
70
78
|
//# sourceMappingURL=clientContracts.d.ts.map
|
package/dist/clientState.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface PendingRequest {
|
|
|
7
7
|
readonly extension: boolean;
|
|
8
8
|
readonly resolve: (value: AcpJsonValue) => void;
|
|
9
9
|
readonly reject: (error: Error) => void;
|
|
10
|
-
readonly timer: ReturnType<typeof setTimeout
|
|
10
|
+
readonly timer: ReturnType<typeof setTimeout> | undefined;
|
|
11
11
|
readonly removeAbortListener: () => void;
|
|
12
12
|
readonly onResponseReceived?: AcpRequestOptions['onResponseReceived'];
|
|
13
13
|
}
|
|
@@ -21,11 +21,11 @@ export declare function deferred<T>(): {
|
|
|
21
21
|
reject: (error: unknown) => void;
|
|
22
22
|
};
|
|
23
23
|
export declare function isCriticalExtensionMethod(method: string): boolean;
|
|
24
|
-
export declare function
|
|
24
|
+
export declare function resolveRequestTimeout(input: {
|
|
25
25
|
readonly options: AcpRequestOptions;
|
|
26
26
|
readonly now: number;
|
|
27
27
|
readonly defaultMs: number;
|
|
28
28
|
readonly maximumMs: number;
|
|
29
|
-
}): number;
|
|
29
|
+
}): number | undefined;
|
|
30
30
|
export declare function cleanupPendingRequest(pending: Map<string, PendingRequest>, entry: PendingRequest): void;
|
|
31
31
|
//# sourceMappingURL=clientState.d.ts.map
|
package/dist/clientState.js
CHANGED
|
@@ -11,12 +11,21 @@ function deferred() {
|
|
|
11
11
|
function isCriticalExtensionMethod(method) {
|
|
12
12
|
return method.startsWith("_") || method.startsWith("$/");
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function resolveRequestTimeout(input) {
|
|
15
|
+
if (input.options.lifetime === "until_settled") {
|
|
16
|
+
if (Reflect.has(input.options, "timeoutMs") || Reflect.has(input.options, "deadlineAt")) {
|
|
17
|
+
throw new TypeError("Until-settled ACP requests cannot select finite timing.");
|
|
18
|
+
}
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
21
|
+
if (input.options.lifetime !== void 0 && input.options.lifetime !== "bounded") {
|
|
22
|
+
throw new TypeError("ACP request lifetime is invalid.");
|
|
23
|
+
}
|
|
15
24
|
const requested = input.options.timeoutMs ?? input.defaultMs;
|
|
16
25
|
if (!Number.isSafeInteger(requested) || requested <= 0 || requested > input.maximumMs) {
|
|
17
26
|
throw new TypeError("ACP request timeout is outside the supported range.");
|
|
18
27
|
}
|
|
19
|
-
if (
|
|
28
|
+
if (input.options.deadlineAt === void 0) return requested;
|
|
20
29
|
const deadline = input.options.deadlineAt instanceof Date ? input.options.deadlineAt.getTime() : input.options.deadlineAt;
|
|
21
30
|
if (!Number.isFinite(deadline)) throw new TypeError("ACP request deadline is invalid.");
|
|
22
31
|
return Math.min(requested, Math.floor(deadline - input.now));
|
|
@@ -27,8 +36,8 @@ function cleanupPendingRequest(pending, entry) {
|
|
|
27
36
|
pending.delete(acpRequestIdKey(entry.id));
|
|
28
37
|
}
|
|
29
38
|
export {
|
|
30
|
-
boundedTimeout,
|
|
31
39
|
cleanupPendingRequest,
|
|
32
40
|
deferred,
|
|
33
|
-
isCriticalExtensionMethod
|
|
41
|
+
isCriticalExtensionMethod,
|
|
42
|
+
resolveRequestTimeout
|
|
34
43
|
};
|
|
@@ -127,10 +127,21 @@ export type AcpStandardCancelParams = AcpStandardObject<{
|
|
|
127
127
|
sessionId: string;
|
|
128
128
|
_meta?: AcpStandardMeta;
|
|
129
129
|
}>;
|
|
130
|
+
export type AcpStandardListSessionsParams = AcpStandardObject<{
|
|
131
|
+
cwd?: string | null;
|
|
132
|
+
cursor?: string | null;
|
|
133
|
+
_meta?: AcpStandardMeta;
|
|
134
|
+
}>;
|
|
135
|
+
export type AcpStandardDeleteSessionParams = AcpStandardObject<{
|
|
136
|
+
sessionId: string;
|
|
137
|
+
_meta?: AcpStandardMeta;
|
|
138
|
+
}>;
|
|
130
139
|
export interface AcpStandardSessionOperations {
|
|
131
140
|
readonly initialize: (params: AcpStandardInitializeParams, options?: AcpRequestOptions) => Promise<AcpJsonValue>;
|
|
132
141
|
readonly newSession: (params: AcpStandardNewSessionParams, options?: AcpRequestOptions) => Promise<AcpJsonValue>;
|
|
133
142
|
readonly loadSession: (params: AcpStandardLoadSessionParams, options?: AcpRequestOptions) => Promise<AcpJsonValue>;
|
|
143
|
+
readonly listSessions: (params: AcpStandardListSessionsParams, options?: AcpRequestOptions) => Promise<AcpJsonValue>;
|
|
144
|
+
readonly deleteSession: (params: AcpStandardDeleteSessionParams, options?: AcpRequestOptions) => Promise<AcpJsonValue>;
|
|
134
145
|
readonly prompt: (params: AcpStandardPromptParams, options?: AcpRequestOptions) => Promise<AcpJsonValue>;
|
|
135
146
|
readonly cancel: (params: AcpStandardCancelParams) => Promise<void>;
|
|
136
147
|
}
|
|
@@ -2,6 +2,8 @@ const STANDARD_METHODS = Object.freeze({
|
|
|
2
2
|
initialize: "initialize",
|
|
3
3
|
newSession: "session/new",
|
|
4
4
|
loadSession: "session/load",
|
|
5
|
+
listSessions: "session/list",
|
|
6
|
+
deleteSession: "session/delete",
|
|
5
7
|
prompt: "session/prompt",
|
|
6
8
|
cancel: "session/cancel"
|
|
7
9
|
});
|
|
@@ -22,6 +24,16 @@ function createAcpStandardSessionOperations(client) {
|
|
|
22
24
|
params,
|
|
23
25
|
options
|
|
24
26
|
),
|
|
27
|
+
listSessions: (params, options) => client.request(
|
|
28
|
+
STANDARD_METHODS.listSessions,
|
|
29
|
+
params,
|
|
30
|
+
options
|
|
31
|
+
),
|
|
32
|
+
deleteSession: (params, options) => client.request(
|
|
33
|
+
STANDARD_METHODS.deleteSession,
|
|
34
|
+
params,
|
|
35
|
+
options
|
|
36
|
+
),
|
|
25
37
|
prompt: (params, options) => client.request(
|
|
26
38
|
STANDARD_METHODS.prompt,
|
|
27
39
|
params,
|