macp-sdk-typescript 0.2.0 → 0.3.0
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/CHANGELOG.md +124 -1
- package/README.md +99 -3
- package/dist/agent/cancel-callback.d.ts +23 -0
- package/dist/agent/cancel-callback.js +108 -0
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.js +1 -0
- package/dist/agent/participant.d.ts +58 -0
- package/dist/agent/participant.js +143 -45
- package/dist/agent/runner.d.ts +34 -1
- package/dist/agent/runner.js +53 -0
- package/dist/agent/strategies.d.ts +2 -0
- package/dist/agent/strategies.js +8 -0
- package/dist/agent/transports.js +5 -0
- package/dist/base-session.d.ts +64 -0
- package/dist/base-session.js +112 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.js +100 -10
- package/dist/constants.d.ts +21 -16
- package/dist/constants.js +24 -17
- package/dist/decision.d.ts +2 -1
- package/dist/decision.js +2 -1
- package/dist/envelope.d.ts +25 -3
- package/dist/envelope.js +42 -11
- package/dist/errors.d.ts +17 -4
- package/dist/errors.js +19 -10
- package/dist/handoff.d.ts +2 -9
- package/dist/handoff.js +2 -17
- package/dist/index.d.ts +3 -1
- package/dist/index.js +10 -2
- package/dist/logging.d.ts +21 -0
- package/dist/logging.js +64 -0
- package/dist/policy.d.ts +47 -42
- package/dist/policy.js +6 -6
- package/dist/projections/base.d.ts +20 -0
- package/dist/projections/base.js +37 -0
- package/dist/projections.d.ts +1 -0
- package/dist/projections.js +1 -0
- package/dist/proposal.d.ts +2 -1
- package/dist/proposal.js +2 -1
- package/dist/quorum.d.ts +2 -1
- package/dist/quorum.js +2 -1
- package/dist/task.d.ts +6 -5
- package/dist/task.js +6 -5
- package/dist/types.d.ts +11 -2
- package/dist/watchers.d.ts +23 -1
- package/dist/watchers.js +59 -1
- package/package.json +2 -2
package/dist/client.js
CHANGED
|
@@ -60,13 +60,45 @@ class AsyncQueue {
|
|
|
60
60
|
else
|
|
61
61
|
this.items.push(item);
|
|
62
62
|
}
|
|
63
|
+
unshift(item) {
|
|
64
|
+
this.items.unshift(item);
|
|
65
|
+
}
|
|
63
66
|
shift() {
|
|
64
67
|
const item = this.items.shift();
|
|
65
68
|
if (item !== undefined)
|
|
66
69
|
return Promise.resolve(item);
|
|
67
70
|
return new Promise((resolve) => this.resolvers.push(resolve));
|
|
68
71
|
}
|
|
72
|
+
shiftWithTimeout(timeoutMs) {
|
|
73
|
+
const item = this.items.shift();
|
|
74
|
+
if (item !== undefined)
|
|
75
|
+
return Promise.resolve(item);
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
let settled = false;
|
|
78
|
+
const resolver = (value) => {
|
|
79
|
+
if (settled) {
|
|
80
|
+
// Timeout already fired; put the value back so it isn't lost.
|
|
81
|
+
this.items.unshift(value);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
settled = true;
|
|
85
|
+
clearTimeout(timer);
|
|
86
|
+
resolve(value);
|
|
87
|
+
};
|
|
88
|
+
this.resolvers.push(resolver);
|
|
89
|
+
const timer = setTimeout(() => {
|
|
90
|
+
if (settled)
|
|
91
|
+
return;
|
|
92
|
+
settled = true;
|
|
93
|
+
const idx = this.resolvers.indexOf(resolver);
|
|
94
|
+
if (idx >= 0)
|
|
95
|
+
this.resolvers.splice(idx, 1);
|
|
96
|
+
resolve(TIMEOUT);
|
|
97
|
+
}, timeoutMs);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
69
100
|
}
|
|
101
|
+
const TIMEOUT = Symbol('stream-read-timeout');
|
|
70
102
|
const STREAM_END = Symbol('stream-end');
|
|
71
103
|
class MacpStream {
|
|
72
104
|
call;
|
|
@@ -109,16 +141,63 @@ class MacpStream {
|
|
|
109
141
|
});
|
|
110
142
|
});
|
|
111
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* RFC-MACP-0006-A1: Send a subscribe-only frame to receive session history
|
|
146
|
+
* + live broadcast. The runtime replays accepted envelopes from
|
|
147
|
+
* `afterSequence` onwards, then continues with live broadcast.
|
|
148
|
+
*/
|
|
149
|
+
sendSubscribe(sessionId, afterSequence = 0) {
|
|
150
|
+
if (this.closed)
|
|
151
|
+
return Promise.reject(new errors_1.MacpSdkError('stream is already closed'));
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
this.call.write({ subscribeSessionId: sessionId, afterSequence }, (error) => {
|
|
154
|
+
if (error)
|
|
155
|
+
reject(error);
|
|
156
|
+
else
|
|
157
|
+
resolve();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
112
161
|
async *responses() {
|
|
113
162
|
while (true) {
|
|
114
163
|
const item = await this.queue.shift();
|
|
115
|
-
if (item === STREAM_END)
|
|
164
|
+
if (item === STREAM_END) {
|
|
165
|
+
// Re-push so a subsequent read()/responses() call also observes end-of-stream.
|
|
166
|
+
this.queue.unshift(STREAM_END);
|
|
116
167
|
return;
|
|
168
|
+
}
|
|
117
169
|
if (item instanceof Error)
|
|
118
170
|
throw item;
|
|
119
171
|
yield item;
|
|
120
172
|
}
|
|
121
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Read a single envelope from the stream. Parity with python-sdk's
|
|
176
|
+
* {@code MacpStream.read(timeout)}.
|
|
177
|
+
*
|
|
178
|
+
* @param timeoutMs Maximum time to wait for the next envelope. If omitted,
|
|
179
|
+
* blocks indefinitely until an envelope arrives, the stream
|
|
180
|
+
* ends, or an error occurs.
|
|
181
|
+
* @returns The next envelope, or {@code null} if the stream has
|
|
182
|
+
* ended.
|
|
183
|
+
* @throws MacpTimeoutError If {@code timeoutMs} elapses before an envelope
|
|
184
|
+
* arrives.
|
|
185
|
+
* @throws MacpTransportError If the underlying stream errored.
|
|
186
|
+
*/
|
|
187
|
+
async read(timeoutMs) {
|
|
188
|
+
const item = timeoutMs === undefined ? await this.queue.shift() : await this.queue.shiftWithTimeout(timeoutMs);
|
|
189
|
+
if (item === TIMEOUT) {
|
|
190
|
+
throw new errors_1.MacpTimeoutError(`stream read timed out after ${timeoutMs}ms`);
|
|
191
|
+
}
|
|
192
|
+
if (item === STREAM_END) {
|
|
193
|
+
// Re-push so future calls (including responses()) also observe the end.
|
|
194
|
+
this.queue.unshift(STREAM_END);
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
if (item instanceof Error)
|
|
198
|
+
throw item;
|
|
199
|
+
return item;
|
|
200
|
+
}
|
|
122
201
|
close() {
|
|
123
202
|
if (this.closed)
|
|
124
203
|
return;
|
|
@@ -144,7 +223,7 @@ class MacpClient {
|
|
|
144
223
|
}
|
|
145
224
|
this.defaultDeadlineMs = options.defaultDeadlineMs;
|
|
146
225
|
this.clientName = options.clientName ?? 'macp-sdk-typescript';
|
|
147
|
-
this.clientVersion = options.clientVersion ?? '0.
|
|
226
|
+
this.clientVersion = options.clientVersion ?? '0.3.0';
|
|
148
227
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
149
228
|
const { protoDir: defaultProtoDir } = require('@multiagentcoordinationprotocol/proto');
|
|
150
229
|
const protoDir = options.protoDir ?? defaultProtoDir;
|
|
@@ -214,7 +293,7 @@ class MacpClient {
|
|
|
214
293
|
websiteUrl: '',
|
|
215
294
|
},
|
|
216
295
|
capabilities: {
|
|
217
|
-
sessions: { stream: true },
|
|
296
|
+
sessions: { stream: true, listSessions: true, watchSessions: true },
|
|
218
297
|
cancellation: { cancelSession: true },
|
|
219
298
|
progress: { progress: true },
|
|
220
299
|
manifest: { getManifest: true },
|
|
@@ -293,6 +372,15 @@ class MacpClient {
|
|
|
293
372
|
const res = await this.unary('ListPolicies', { mode: mode || '' }, auth, options?.deadlineMs);
|
|
294
373
|
return res.descriptors || [];
|
|
295
374
|
}
|
|
375
|
+
async listSessions(options) {
|
|
376
|
+
const auth = this.requireAuth(options?.auth);
|
|
377
|
+
const res = await this.unary('ListSessions', {}, auth, options?.deadlineMs);
|
|
378
|
+
return res.sessions || [];
|
|
379
|
+
}
|
|
380
|
+
watchSessions(auth) {
|
|
381
|
+
const metadata = this.metadata(auth);
|
|
382
|
+
return metadata ? this.client.WatchSessions({}, metadata) : this.client.WatchSessions({});
|
|
383
|
+
}
|
|
296
384
|
watchPolicies(auth) {
|
|
297
385
|
const metadata = this.metadata(auth);
|
|
298
386
|
return metadata ? this.client.WatchPolicies({}, metadata) : this.client.WatchPolicies({});
|
|
@@ -339,12 +427,13 @@ class MacpClient {
|
|
|
339
427
|
(0, validation_1.validateSignalType)(options.signalType, options.data);
|
|
340
428
|
const auth = this.requireAuth(options.auth);
|
|
341
429
|
(0, auth_1.assertSenderMatchesIdentity)(auth, options.sender);
|
|
342
|
-
const
|
|
430
|
+
const signalPayload = (0, envelope_1.buildSignalPayload)({
|
|
343
431
|
signalType: options.signalType,
|
|
344
|
-
data: options.data
|
|
345
|
-
confidence: options.confidence
|
|
346
|
-
correlationSessionId: options.correlationSessionId
|
|
432
|
+
data: options.data,
|
|
433
|
+
confidence: options.confidence,
|
|
434
|
+
correlationSessionId: options.correlationSessionId,
|
|
347
435
|
});
|
|
436
|
+
const payload = this.protoRegistry.encodeKnownPayload('', 'Signal', signalPayload);
|
|
348
437
|
const envelope = (0, envelope_1.buildEnvelope)({
|
|
349
438
|
mode: '',
|
|
350
439
|
messageType: 'Signal',
|
|
@@ -357,13 +446,14 @@ class MacpClient {
|
|
|
357
446
|
async sendProgress(options) {
|
|
358
447
|
const auth = this.requireAuth(options.auth);
|
|
359
448
|
(0, auth_1.assertSenderMatchesIdentity)(auth, options.sender);
|
|
360
|
-
const
|
|
449
|
+
const progressPayload = (0, envelope_1.buildProgressPayload)({
|
|
361
450
|
progressToken: options.progressToken,
|
|
362
451
|
progress: options.progress,
|
|
363
452
|
total: options.total,
|
|
364
|
-
message: options.message
|
|
365
|
-
targetMessageId: options.targetMessageId
|
|
453
|
+
message: options.message,
|
|
454
|
+
targetMessageId: options.targetMessageId,
|
|
366
455
|
});
|
|
456
|
+
const payload = this.protoRegistry.encodeKnownPayload('', 'Progress', progressPayload);
|
|
367
457
|
const envelope = (0, envelope_1.buildEnvelope)({
|
|
368
458
|
mode: options.mode ?? '',
|
|
369
459
|
messageType: 'Progress',
|
package/dist/constants.d.ts
CHANGED
|
@@ -8,19 +8,24 @@ export declare const MODE_TASK = "macp.mode.task.v1";
|
|
|
8
8
|
export declare const MODE_HANDOFF = "macp.mode.handoff.v1";
|
|
9
9
|
export declare const MODE_QUORUM = "macp.mode.quorum.v1";
|
|
10
10
|
export declare const MODE_MULTI_ROUND = "ext.multi_round.v1";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export declare const
|
|
16
|
-
export declare const
|
|
17
|
-
export declare const
|
|
18
|
-
export declare const
|
|
19
|
-
export declare const
|
|
20
|
-
export declare const
|
|
21
|
-
export declare const
|
|
22
|
-
export declare const
|
|
23
|
-
export declare const
|
|
24
|
-
export declare const
|
|
25
|
-
export declare const
|
|
26
|
-
export declare const
|
|
11
|
+
/**
|
|
12
|
+
* The five first-class coordination modes. Parity with
|
|
13
|
+
* python-sdk `macp_sdk.constants.STANDARD_MODES`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const STANDARD_MODES: readonly ["macp.mode.decision.v1", "macp.mode.proposal.v1", "macp.mode.task.v1", "macp.mode.handoff.v1", "macp.mode.quorum.v1"];
|
|
16
|
+
export declare const UNSUPPORTED_PROTOCOL_VERSION = "UNSUPPORTED_PROTOCOL_VERSION";
|
|
17
|
+
export declare const INVALID_ENVELOPE = "INVALID_ENVELOPE";
|
|
18
|
+
export declare const SESSION_ALREADY_EXISTS = "SESSION_ALREADY_EXISTS";
|
|
19
|
+
export declare const SESSION_NOT_FOUND = "SESSION_NOT_FOUND";
|
|
20
|
+
export declare const SESSION_NOT_OPEN = "SESSION_NOT_OPEN";
|
|
21
|
+
export declare const MODE_NOT_SUPPORTED = "MODE_NOT_SUPPORTED";
|
|
22
|
+
export declare const FORBIDDEN = "FORBIDDEN";
|
|
23
|
+
export declare const UNAUTHENTICATED = "UNAUTHENTICATED";
|
|
24
|
+
export declare const DUPLICATE_MESSAGE = "DUPLICATE_MESSAGE";
|
|
25
|
+
export declare const PAYLOAD_TOO_LARGE = "PAYLOAD_TOO_LARGE";
|
|
26
|
+
export declare const RATE_LIMITED = "RATE_LIMITED";
|
|
27
|
+
export declare const INTERNAL_ERROR = "INTERNAL_ERROR";
|
|
28
|
+
export declare const POLICY_DENIED = "POLICY_DENIED";
|
|
29
|
+
export declare const INVALID_SESSION_ID = "INVALID_SESSION_ID";
|
|
30
|
+
export declare const UNKNOWN_POLICY_VERSION = "UNKNOWN_POLICY_VERSION";
|
|
31
|
+
export declare const INVALID_POLICY_DEFINITION = "INVALID_POLICY_DEFINITION";
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.INVALID_POLICY_DEFINITION = exports.UNKNOWN_POLICY_VERSION = exports.INVALID_SESSION_ID = exports.POLICY_DENIED = exports.INTERNAL_ERROR = exports.RATE_LIMITED = exports.PAYLOAD_TOO_LARGE = exports.DUPLICATE_MESSAGE = exports.UNAUTHENTICATED = exports.FORBIDDEN = exports.MODE_NOT_SUPPORTED = exports.SESSION_NOT_OPEN = exports.SESSION_NOT_FOUND = exports.SESSION_ALREADY_EXISTS = exports.INVALID_ENVELOPE = exports.UNSUPPORTED_PROTOCOL_VERSION = exports.STANDARD_MODES = exports.MODE_MULTI_ROUND = exports.MODE_QUORUM = exports.MODE_HANDOFF = exports.MODE_TASK = exports.MODE_PROPOSAL = exports.MODE_DECISION = exports.DEFAULT_POLICY_VERSION = exports.DEFAULT_CONFIGURATION_VERSION = exports.DEFAULT_MODE_VERSION = exports.MACP_VERSION = void 0;
|
|
4
4
|
exports.MACP_VERSION = '1.0';
|
|
5
5
|
exports.DEFAULT_MODE_VERSION = '1.0.0';
|
|
6
6
|
exports.DEFAULT_CONFIGURATION_VERSION = 'config.default';
|
|
@@ -11,19 +11,26 @@ exports.MODE_TASK = 'macp.mode.task.v1';
|
|
|
11
11
|
exports.MODE_HANDOFF = 'macp.mode.handoff.v1';
|
|
12
12
|
exports.MODE_QUORUM = 'macp.mode.quorum.v1';
|
|
13
13
|
exports.MODE_MULTI_ROUND = 'ext.multi_round.v1';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
exports.
|
|
19
|
-
|
|
20
|
-
exports
|
|
21
|
-
exports.
|
|
22
|
-
exports.
|
|
23
|
-
exports.
|
|
24
|
-
exports.
|
|
25
|
-
exports.
|
|
26
|
-
exports.
|
|
27
|
-
exports.
|
|
28
|
-
exports.
|
|
29
|
-
exports.
|
|
14
|
+
/**
|
|
15
|
+
* The five first-class coordination modes. Parity with
|
|
16
|
+
* python-sdk `macp_sdk.constants.STANDARD_MODES`.
|
|
17
|
+
*/
|
|
18
|
+
exports.STANDARD_MODES = [exports.MODE_DECISION, exports.MODE_PROPOSAL, exports.MODE_TASK, exports.MODE_HANDOFF, exports.MODE_QUORUM];
|
|
19
|
+
// Well-known error codes. Names match the on-the-wire strings the runtime
|
|
20
|
+
// emits and python-sdk's exports (no ERR_ prefix).
|
|
21
|
+
exports.UNSUPPORTED_PROTOCOL_VERSION = 'UNSUPPORTED_PROTOCOL_VERSION';
|
|
22
|
+
exports.INVALID_ENVELOPE = 'INVALID_ENVELOPE';
|
|
23
|
+
exports.SESSION_ALREADY_EXISTS = 'SESSION_ALREADY_EXISTS';
|
|
24
|
+
exports.SESSION_NOT_FOUND = 'SESSION_NOT_FOUND';
|
|
25
|
+
exports.SESSION_NOT_OPEN = 'SESSION_NOT_OPEN';
|
|
26
|
+
exports.MODE_NOT_SUPPORTED = 'MODE_NOT_SUPPORTED';
|
|
27
|
+
exports.FORBIDDEN = 'FORBIDDEN';
|
|
28
|
+
exports.UNAUTHENTICATED = 'UNAUTHENTICATED';
|
|
29
|
+
exports.DUPLICATE_MESSAGE = 'DUPLICATE_MESSAGE';
|
|
30
|
+
exports.PAYLOAD_TOO_LARGE = 'PAYLOAD_TOO_LARGE';
|
|
31
|
+
exports.RATE_LIMITED = 'RATE_LIMITED';
|
|
32
|
+
exports.INTERNAL_ERROR = 'INTERNAL_ERROR';
|
|
33
|
+
exports.POLICY_DENIED = 'POLICY_DENIED';
|
|
34
|
+
exports.INVALID_SESSION_ID = 'INVALID_SESSION_ID';
|
|
35
|
+
exports.UNKNOWN_POLICY_VERSION = 'UNKNOWN_POLICY_VERSION';
|
|
36
|
+
exports.INVALID_POLICY_DEFINITION = 'INVALID_POLICY_DEFINITION';
|
package/dist/decision.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ export declare class DecisionSession {
|
|
|
24
24
|
intent: string;
|
|
25
25
|
participants: string[];
|
|
26
26
|
ttlMs: number;
|
|
27
|
-
|
|
27
|
+
contextId?: string;
|
|
28
|
+
extensions?: Record<string, Buffer>;
|
|
28
29
|
roots?: {
|
|
29
30
|
uri: string;
|
|
30
31
|
name?: string;
|
package/dist/decision.js
CHANGED
|
@@ -47,7 +47,8 @@ class DecisionSession {
|
|
|
47
47
|
intent: input.intent,
|
|
48
48
|
participants: input.participants,
|
|
49
49
|
ttlMs: input.ttlMs,
|
|
50
|
-
|
|
50
|
+
contextId: input.contextId,
|
|
51
|
+
extensions: input.extensions,
|
|
51
52
|
roots: input.roots,
|
|
52
53
|
modeVersion: this.modeVersion,
|
|
53
54
|
configurationVersion: this.configurationVersion,
|
package/dist/envelope.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { CommitmentPayload, Envelope, Root, SessionStartPayload } from './types';
|
|
1
|
+
import type { CommitmentPayload, Envelope, ProgressPayload, Root, SessionStartPayload, SignalPayload } from './types';
|
|
2
2
|
export declare function newSessionId(): string;
|
|
3
3
|
export declare function newMessageId(): string;
|
|
4
4
|
export declare function newCommitmentId(): string;
|
|
5
5
|
export declare function nowUnixMs(): number;
|
|
6
|
-
export declare function encodeContext(context?: Buffer | string | Record<string, unknown>): Buffer;
|
|
7
6
|
export declare function buildSessionStartPayload(input: {
|
|
8
7
|
intent: string;
|
|
9
8
|
participants: string[];
|
|
@@ -11,7 +10,8 @@ export declare function buildSessionStartPayload(input: {
|
|
|
11
10
|
modeVersion?: string;
|
|
12
11
|
configurationVersion?: string;
|
|
13
12
|
policyVersion?: string;
|
|
14
|
-
|
|
13
|
+
contextId?: string;
|
|
14
|
+
extensions?: Record<string, Buffer>;
|
|
15
15
|
roots?: Root[];
|
|
16
16
|
}): SessionStartPayload;
|
|
17
17
|
export declare function inferOutcomePositive(action: string): boolean;
|
|
@@ -26,6 +26,27 @@ export declare function buildCommitmentPayload(input: {
|
|
|
26
26
|
outcomePositive?: boolean;
|
|
27
27
|
}): CommitmentPayload;
|
|
28
28
|
export declare function buildRoot(uri: string, name?: string): Root;
|
|
29
|
+
export declare function buildSignalPayload(input: {
|
|
30
|
+
signalType: string;
|
|
31
|
+
data?: Buffer | Uint8Array;
|
|
32
|
+
confidence?: number;
|
|
33
|
+
correlationSessionId?: string;
|
|
34
|
+
}): SignalPayload;
|
|
35
|
+
export declare function buildProgressPayload(input: {
|
|
36
|
+
progressToken: string;
|
|
37
|
+
progress: number;
|
|
38
|
+
total: number;
|
|
39
|
+
message?: string;
|
|
40
|
+
targetMessageId?: string;
|
|
41
|
+
}): ProgressPayload;
|
|
42
|
+
type ProtoSerializable = {
|
|
43
|
+
serializeBinary(): Uint8Array;
|
|
44
|
+
} | {
|
|
45
|
+
toBinary(): Uint8Array;
|
|
46
|
+
} | {
|
|
47
|
+
finish(): Uint8Array;
|
|
48
|
+
};
|
|
49
|
+
export declare function serializeMessage(message: ProtoSerializable | unknown): Uint8Array;
|
|
29
50
|
/**
|
|
30
51
|
* Type-erasure helper for protobuf payload encoders.
|
|
31
52
|
*
|
|
@@ -48,3 +69,4 @@ export declare function buildEnvelope(input: {
|
|
|
48
69
|
macpVersion?: string;
|
|
49
70
|
timestampUnixMs?: string | number;
|
|
50
71
|
}): Envelope;
|
|
72
|
+
export {};
|
package/dist/envelope.js
CHANGED
|
@@ -4,11 +4,13 @@ exports.newSessionId = newSessionId;
|
|
|
4
4
|
exports.newMessageId = newMessageId;
|
|
5
5
|
exports.newCommitmentId = newCommitmentId;
|
|
6
6
|
exports.nowUnixMs = nowUnixMs;
|
|
7
|
-
exports.encodeContext = encodeContext;
|
|
8
7
|
exports.buildSessionStartPayload = buildSessionStartPayload;
|
|
9
8
|
exports.inferOutcomePositive = inferOutcomePositive;
|
|
10
9
|
exports.buildCommitmentPayload = buildCommitmentPayload;
|
|
11
10
|
exports.buildRoot = buildRoot;
|
|
11
|
+
exports.buildSignalPayload = buildSignalPayload;
|
|
12
|
+
exports.buildProgressPayload = buildProgressPayload;
|
|
13
|
+
exports.serializeMessage = serializeMessage;
|
|
12
14
|
exports.toProtoPayload = toProtoPayload;
|
|
13
15
|
exports.buildEnvelope = buildEnvelope;
|
|
14
16
|
const node_crypto_1 = require("node:crypto");
|
|
@@ -25,15 +27,6 @@ function newCommitmentId() {
|
|
|
25
27
|
function nowUnixMs() {
|
|
26
28
|
return Date.now();
|
|
27
29
|
}
|
|
28
|
-
function encodeContext(context) {
|
|
29
|
-
if (!context)
|
|
30
|
-
return Buffer.alloc(0);
|
|
31
|
-
if (Buffer.isBuffer(context))
|
|
32
|
-
return context;
|
|
33
|
-
if (typeof context === 'string')
|
|
34
|
-
return Buffer.from(context, 'utf8');
|
|
35
|
-
return Buffer.from(JSON.stringify(context), 'utf8');
|
|
36
|
-
}
|
|
37
30
|
function buildSessionStartPayload(input) {
|
|
38
31
|
return {
|
|
39
32
|
intent: input.intent,
|
|
@@ -42,7 +35,8 @@ function buildSessionStartPayload(input) {
|
|
|
42
35
|
configurationVersion: input.configurationVersion ?? constants_1.DEFAULT_CONFIGURATION_VERSION,
|
|
43
36
|
policyVersion: input.policyVersion ?? constants_1.DEFAULT_POLICY_VERSION,
|
|
44
37
|
ttlMs: input.ttlMs,
|
|
45
|
-
|
|
38
|
+
contextId: input.contextId ?? '',
|
|
39
|
+
extensions: input.extensions ?? {},
|
|
46
40
|
roots: input.roots ?? [],
|
|
47
41
|
};
|
|
48
42
|
}
|
|
@@ -68,6 +62,43 @@ function buildCommitmentPayload(input) {
|
|
|
68
62
|
function buildRoot(uri, name = '') {
|
|
69
63
|
return { uri, name };
|
|
70
64
|
}
|
|
65
|
+
function buildSignalPayload(input) {
|
|
66
|
+
const data = input.data instanceof Buffer ? input.data : input.data ? Buffer.from(input.data) : Buffer.alloc(0);
|
|
67
|
+
return {
|
|
68
|
+
signalType: input.signalType,
|
|
69
|
+
data,
|
|
70
|
+
confidence: input.confidence ?? 0,
|
|
71
|
+
correlationSessionId: input.correlationSessionId ?? '',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function buildProgressPayload(input) {
|
|
75
|
+
return {
|
|
76
|
+
progressToken: input.progressToken,
|
|
77
|
+
progress: input.progress,
|
|
78
|
+
total: input.total,
|
|
79
|
+
message: input.message ?? '',
|
|
80
|
+
targetMessageId: input.targetMessageId ?? '',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function serializeMessage(message) {
|
|
84
|
+
// Parity with python-sdk `envelope.serialize_message`: invoke the protobuf
|
|
85
|
+
// serializer exposed on the message. Supports objects with `serializeBinary`
|
|
86
|
+
// (protoc-gen-js), `toBinary` (protobuf-es / ts-proto), or `finish`
|
|
87
|
+
// (protobufjs Writer). For plain JS interface payloads, use
|
|
88
|
+
// `ProtoRegistry.encodeKnownPayload(mode, messageType, payload)` instead —
|
|
89
|
+
// the registry owns the mode/messageType → descriptor mapping.
|
|
90
|
+
const candidate = message;
|
|
91
|
+
if (typeof candidate?.serializeBinary === 'function') {
|
|
92
|
+
return candidate.serializeBinary();
|
|
93
|
+
}
|
|
94
|
+
if (typeof candidate?.toBinary === 'function') {
|
|
95
|
+
return candidate.toBinary();
|
|
96
|
+
}
|
|
97
|
+
if (typeof candidate?.finish === 'function') {
|
|
98
|
+
return candidate.finish();
|
|
99
|
+
}
|
|
100
|
+
throw new TypeError('serializeMessage: object is not a protobuf message — expected serializeBinary(), toBinary(), or finish() method. For plain JS payloads, use ProtoRegistry.encodeKnownPayload().');
|
|
101
|
+
}
|
|
71
102
|
/**
|
|
72
103
|
* Type-erasure helper for protobuf payload encoders.
|
|
73
104
|
*
|
package/dist/errors.d.ts
CHANGED
|
@@ -5,6 +5,18 @@ export declare class MacpSdkError extends Error {
|
|
|
5
5
|
export declare class MacpTransportError extends MacpSdkError {
|
|
6
6
|
constructor(message: string);
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Structured NACK record. Mirrors python-sdk's `AckFailure` dataclass so
|
|
10
|
+
* cross-SDK code can share the same shape when logging or persisting a
|
|
11
|
+
* rejected message.
|
|
12
|
+
*/
|
|
13
|
+
export interface AckFailure {
|
|
14
|
+
code: string;
|
|
15
|
+
message: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
messageId: string;
|
|
18
|
+
reasons: string[];
|
|
19
|
+
}
|
|
8
20
|
export declare class MacpAckError extends MacpSdkError {
|
|
9
21
|
readonly ack: Ack;
|
|
10
22
|
/** Optional gRPC trailing metadata for extracting additional error details. */
|
|
@@ -12,14 +24,15 @@ export declare class MacpAckError extends MacpSdkError {
|
|
|
12
24
|
key: string;
|
|
13
25
|
value: string | Buffer;
|
|
14
26
|
}>;
|
|
27
|
+
/** Structured NACK record — parity with python-sdk `MacpAckError.failure`. */
|
|
28
|
+
readonly failure: AckFailure;
|
|
15
29
|
constructor(ack: Ack, grpcMetadata?: Array<{
|
|
16
30
|
key: string;
|
|
17
31
|
value: string | Buffer;
|
|
18
32
|
}>);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
private _parseGrpcMetadataReasons;
|
|
33
|
+
private static _extractReasons;
|
|
34
|
+
private static _parseAckReasons;
|
|
35
|
+
private static _parseGrpcMetadataReasons;
|
|
23
36
|
}
|
|
24
37
|
export declare class MacpSessionError extends MacpSdkError {
|
|
25
38
|
constructor(message: string);
|
package/dist/errors.js
CHANGED
|
@@ -19,26 +19,35 @@ class MacpAckError extends MacpSdkError {
|
|
|
19
19
|
ack;
|
|
20
20
|
/** Optional gRPC trailing metadata for extracting additional error details. */
|
|
21
21
|
grpcMetadata;
|
|
22
|
+
/** Structured NACK record — parity with python-sdk `MacpAckError.failure`. */
|
|
23
|
+
failure;
|
|
22
24
|
constructor(ack, grpcMetadata) {
|
|
23
25
|
super(`${ack.error?.code ?? 'UNKNOWN'}: ${ack.error?.message ?? 'runtime returned nack'}`);
|
|
24
26
|
this.name = 'MacpAckError';
|
|
25
27
|
this.ack = ack;
|
|
26
28
|
this.grpcMetadata = grpcMetadata;
|
|
29
|
+
const reasons = MacpAckError._extractReasons(ack, grpcMetadata);
|
|
30
|
+
this.failure = {
|
|
31
|
+
code: ack.error?.code ?? 'UNKNOWN',
|
|
32
|
+
message: ack.error?.message ?? 'runtime returned nack',
|
|
33
|
+
sessionId: ack.sessionId ?? ack.error?.sessionId ?? '',
|
|
34
|
+
messageId: ack.messageId ?? ack.error?.messageId ?? '',
|
|
35
|
+
reasons,
|
|
36
|
+
};
|
|
27
37
|
}
|
|
28
|
-
|
|
29
|
-
get reasons() {
|
|
38
|
+
static _extractReasons(ack, grpcMetadata) {
|
|
30
39
|
// First try: parse from ack.error.details (matches Python _parse_ack_reasons)
|
|
31
|
-
const fromDetails =
|
|
40
|
+
const fromDetails = MacpAckError._parseAckReasons(ack);
|
|
32
41
|
if (fromDetails.length > 0)
|
|
33
42
|
return fromDetails;
|
|
34
43
|
// Second try: parse from gRPC trailing metadata (matches Python _parse_grpc_metadata_reasons)
|
|
35
|
-
return
|
|
44
|
+
return MacpAckError._parseGrpcMetadataReasons(grpcMetadata);
|
|
36
45
|
}
|
|
37
|
-
_parseAckReasons() {
|
|
38
|
-
if (!
|
|
46
|
+
static _parseAckReasons(ack) {
|
|
47
|
+
if (!ack.error?.details)
|
|
39
48
|
return [];
|
|
40
49
|
try {
|
|
41
|
-
const details =
|
|
50
|
+
const details = ack.error.details;
|
|
42
51
|
const raw = Buffer.isBuffer(details) ? details.toString('utf-8') : String(details);
|
|
43
52
|
const parsed = JSON.parse(raw);
|
|
44
53
|
const reasons = parsed.reasons;
|
|
@@ -48,11 +57,11 @@ class MacpAckError extends MacpSdkError {
|
|
|
48
57
|
return [];
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
|
-
_parseGrpcMetadataReasons() {
|
|
52
|
-
if (!
|
|
60
|
+
static _parseGrpcMetadataReasons(grpcMetadata) {
|
|
61
|
+
if (!grpcMetadata)
|
|
53
62
|
return [];
|
|
54
63
|
try {
|
|
55
|
-
for (const item of
|
|
64
|
+
for (const item of grpcMetadata) {
|
|
56
65
|
if (item.key === 'macp-error-details-bin') {
|
|
57
66
|
const data = Buffer.isBuffer(item.value)
|
|
58
67
|
? item.value.toString('utf-8')
|
package/dist/handoff.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ export declare class HandoffSession {
|
|
|
24
24
|
intent: string;
|
|
25
25
|
participants: string[];
|
|
26
26
|
ttlMs: number;
|
|
27
|
-
|
|
27
|
+
contextId?: string;
|
|
28
|
+
extensions?: Record<string, Buffer>;
|
|
28
29
|
roots?: {
|
|
29
30
|
uri: string;
|
|
30
31
|
name?: string;
|
|
@@ -39,14 +40,6 @@ export declare class HandoffSession {
|
|
|
39
40
|
sender?: string;
|
|
40
41
|
auth?: AuthConfig;
|
|
41
42
|
}): Promise<Ack>;
|
|
42
|
-
/**
|
|
43
|
-
* @deprecated Use {@link addContext} instead. Scheduled for removal in 0.4.0.
|
|
44
|
-
* First call logs a one-shot warning to guide migrations without spamming long-lived processes.
|
|
45
|
-
*/
|
|
46
|
-
sendContext(input: HandoffContextPayload & {
|
|
47
|
-
sender?: string;
|
|
48
|
-
auth?: AuthConfig;
|
|
49
|
-
}): Promise<Ack>;
|
|
50
43
|
acceptHandoff(input: HandoffAcceptPayload & {
|
|
51
44
|
sender?: string;
|
|
52
45
|
auth?: AuthConfig;
|
package/dist/handoff.js
CHANGED
|
@@ -6,14 +6,6 @@ const constants_1 = require("./constants");
|
|
|
6
6
|
const envelope_1 = require("./envelope");
|
|
7
7
|
const handoff_1 = require("./projections/handoff");
|
|
8
8
|
const validation_1 = require("./validation");
|
|
9
|
-
let sendContextWarned = false;
|
|
10
|
-
function warnSendContextOnce() {
|
|
11
|
-
if (sendContextWarned)
|
|
12
|
-
return;
|
|
13
|
-
sendContextWarned = true;
|
|
14
|
-
// eslint-disable-next-line no-console
|
|
15
|
-
console.warn('[macp-sdk-typescript] HandoffSession.sendContext() is deprecated and will be removed in 0.4.0. Use addContext() instead.');
|
|
16
|
-
}
|
|
17
9
|
class HandoffSession {
|
|
18
10
|
client;
|
|
19
11
|
sessionId;
|
|
@@ -55,7 +47,8 @@ class HandoffSession {
|
|
|
55
47
|
intent: input.intent,
|
|
56
48
|
participants: input.participants,
|
|
57
49
|
ttlMs: input.ttlMs,
|
|
58
|
-
|
|
50
|
+
contextId: input.contextId,
|
|
51
|
+
extensions: input.extensions,
|
|
59
52
|
roots: input.roots,
|
|
60
53
|
modeVersion: this.modeVersion,
|
|
61
54
|
configurationVersion: this.configurationVersion,
|
|
@@ -94,14 +87,6 @@ class HandoffSession {
|
|
|
94
87
|
});
|
|
95
88
|
return this.sendAndTrack(envelope, input.auth);
|
|
96
89
|
}
|
|
97
|
-
/**
|
|
98
|
-
* @deprecated Use {@link addContext} instead. Scheduled for removal in 0.4.0.
|
|
99
|
-
* First call logs a one-shot warning to guide migrations without spamming long-lived processes.
|
|
100
|
-
*/
|
|
101
|
-
async sendContext(input) {
|
|
102
|
-
warnSendContextOnce();
|
|
103
|
-
return this.addContext(input);
|
|
104
|
-
}
|
|
105
90
|
async acceptHandoff(input) {
|
|
106
91
|
(0, validation_1.validateRequiredField)('handoffId', input.handoffId);
|
|
107
92
|
const envelope = (0, envelope_1.buildEnvelope)({
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { Auth, type AuthConfig, type BearerAuthOptions } from './auth';
|
|
2
|
+
export * from './base-session';
|
|
2
3
|
export * from './client';
|
|
3
4
|
export * from './constants';
|
|
4
5
|
export * from './decision';
|
|
5
6
|
export * from './envelope';
|
|
6
7
|
export * from './errors';
|
|
7
8
|
export * from './handoff';
|
|
9
|
+
export * from './logging';
|
|
8
10
|
export * from './policy';
|
|
9
11
|
export * from './projections';
|
|
10
12
|
export * from './proposal';
|
package/dist/index.js
CHANGED
|
@@ -36,14 +36,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.agent = void 0;
|
|
40
|
-
|
|
39
|
+
exports.agent = exports.Auth = void 0;
|
|
40
|
+
// Auth: export only the public constructors and types. The helpers
|
|
41
|
+
// `validateAuth`, `authSender`, `assertSenderMatchesIdentity`, and
|
|
42
|
+
// `metadataFromAuth` are SDK-internal — importable from the `./auth`
|
|
43
|
+
// submodule if needed, but intentionally absent from the top-level surface
|
|
44
|
+
// to match python-sdk's `__all__` (which only exposes `AuthConfig`).
|
|
45
|
+
var auth_1 = require("./auth");
|
|
46
|
+
Object.defineProperty(exports, "Auth", { enumerable: true, get: function () { return auth_1.Auth; } });
|
|
47
|
+
__exportStar(require("./base-session"), exports);
|
|
41
48
|
__exportStar(require("./client"), exports);
|
|
42
49
|
__exportStar(require("./constants"), exports);
|
|
43
50
|
__exportStar(require("./decision"), exports);
|
|
44
51
|
__exportStar(require("./envelope"), exports);
|
|
45
52
|
__exportStar(require("./errors"), exports);
|
|
46
53
|
__exportStar(require("./handoff"), exports);
|
|
54
|
+
__exportStar(require("./logging"), exports);
|
|
47
55
|
__exportStar(require("./policy"), exports);
|
|
48
56
|
__exportStar(require("./projections"), exports);
|
|
49
57
|
__exportStar(require("./proposal"), exports);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logger for the MACP SDK.
|
|
3
|
+
*
|
|
4
|
+
* Parity with python-sdk's `macp_sdk._logging.logger` + `configure_logging()`:
|
|
5
|
+
* production Node apps need controllable log levels (silent by default-ish,
|
|
6
|
+
* opt-in verbose) and the ability to re-route to Pino / Winston / etc.
|
|
7
|
+
*/
|
|
8
|
+
export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
|
|
9
|
+
export type LogSink = (level: Exclude<LogLevel, 'silent'>, args: unknown[]) => void;
|
|
10
|
+
export declare const logger: {
|
|
11
|
+
error: (...args: unknown[]) => void;
|
|
12
|
+
warn: (...args: unknown[]) => void;
|
|
13
|
+
info: (...args: unknown[]) => void;
|
|
14
|
+
debug: (...args: unknown[]) => void;
|
|
15
|
+
};
|
|
16
|
+
export declare function configureLogging(options: {
|
|
17
|
+
level?: LogLevel;
|
|
18
|
+
sink?: LogSink;
|
|
19
|
+
}): void;
|
|
20
|
+
/** Test-only: reset to env-derived level + default sink. */
|
|
21
|
+
export declare function _resetLoggingForTests(): void;
|