macp-sdk-typescript 0.2.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/LICENSE +201 -0
  3. package/README.md +307 -0
  4. package/dist/agent/dispatcher.d.ts +16 -0
  5. package/dist/agent/dispatcher.js +61 -0
  6. package/dist/agent/index.d.ts +6 -0
  7. package/dist/agent/index.js +25 -0
  8. package/dist/agent/participant.d.ts +38 -0
  9. package/dist/agent/participant.js +221 -0
  10. package/dist/agent/runner.d.ts +18 -0
  11. package/dist/agent/runner.js +84 -0
  12. package/dist/agent/strategies.d.ts +40 -0
  13. package/dist/agent/strategies.js +106 -0
  14. package/dist/agent/transports.d.ts +35 -0
  15. package/dist/agent/transports.js +125 -0
  16. package/dist/agent/types.d.ts +72 -0
  17. package/dist/agent/types.js +2 -0
  18. package/dist/auth.d.ts +52 -0
  19. package/dist/auth.js +112 -0
  20. package/dist/client.d.ts +171 -0
  21. package/dist/client.js +384 -0
  22. package/dist/constants.d.ts +26 -0
  23. package/dist/constants.js +29 -0
  24. package/dist/decision.d.ts +65 -0
  25. package/dist/decision.js +148 -0
  26. package/dist/envelope.d.ts +50 -0
  27. package/dist/envelope.js +97 -0
  28. package/dist/errors.d.ts +44 -0
  29. package/dist/errors.js +114 -0
  30. package/dist/handoff.d.ts +73 -0
  31. package/dist/handoff.js +160 -0
  32. package/dist/index.d.ts +18 -0
  33. package/dist/index.js +57 -0
  34. package/dist/policy.d.ts +76 -0
  35. package/dist/policy.js +118 -0
  36. package/dist/projections/decision.d.ts +49 -0
  37. package/dist/projections/decision.js +132 -0
  38. package/dist/projections/handoff.d.ts +28 -0
  39. package/dist/projections/handoff.js +111 -0
  40. package/dist/projections/proposal.d.ts +40 -0
  41. package/dist/projections/proposal.js +123 -0
  42. package/dist/projections/quorum.d.ts +36 -0
  43. package/dist/projections/quorum.js +107 -0
  44. package/dist/projections/task.d.ts +54 -0
  45. package/dist/projections/task.js +127 -0
  46. package/dist/projections.d.ts +5 -0
  47. package/dist/projections.js +21 -0
  48. package/dist/proposal.d.ts +69 -0
  49. package/dist/proposal.js +155 -0
  50. package/dist/proto-registry.d.ts +12 -0
  51. package/dist/proto-registry.js +165 -0
  52. package/dist/quorum.d.ts +65 -0
  53. package/dist/quorum.js +144 -0
  54. package/dist/retry.d.ts +14 -0
  55. package/dist/retry.js +48 -0
  56. package/dist/task.d.ts +73 -0
  57. package/dist/task.js +166 -0
  58. package/dist/types.d.ts +263 -0
  59. package/dist/types.js +2 -0
  60. package/dist/validation.d.ts +17 -0
  61. package/dist/validation.js +92 -0
  62. package/dist/watchers.d.ts +47 -0
  63. package/dist/watchers.js +176 -0
  64. package/package.json +72 -0
package/dist/client.js ADDED
@@ -0,0 +1,384 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MacpClient = exports.MacpStream = void 0;
37
+ /* eslint-disable @typescript-eslint/no-explicit-any --
38
+ * The gRPC service client returned by `protoLoader.loadSync()` is typed as
39
+ * `any` by `@grpc/proto-loader`; method signatures (Send, StreamSession,
40
+ * WatchModeRegistry, …) are runtime-generated. Narrowing these with hand-rolled
41
+ * interfaces would drift as the proto evolves. This file isolates that `any`
42
+ * boundary — no other file in `src/` should need the rule disabled. See
43
+ * CLAUDE.md (`warnings for \`any\` in gRPC layer are expected`).
44
+ */
45
+ const path = __importStar(require("node:path"));
46
+ const grpc = __importStar(require("@grpc/grpc-js"));
47
+ const protoLoader = __importStar(require("@grpc/proto-loader"));
48
+ const auth_1 = require("./auth");
49
+ const envelope_1 = require("./envelope");
50
+ const errors_1 = require("./errors");
51
+ const proto_registry_1 = require("./proto-registry");
52
+ const validation_1 = require("./validation");
53
+ class AsyncQueue {
54
+ items = [];
55
+ resolvers = [];
56
+ push(item) {
57
+ const resolve = this.resolvers.shift();
58
+ if (resolve)
59
+ resolve(item);
60
+ else
61
+ this.items.push(item);
62
+ }
63
+ shift() {
64
+ const item = this.items.shift();
65
+ if (item !== undefined)
66
+ return Promise.resolve(item);
67
+ return new Promise((resolve) => this.resolvers.push(resolve));
68
+ }
69
+ }
70
+ const STREAM_END = Symbol('stream-end');
71
+ class MacpStream {
72
+ call;
73
+ queue = new AsyncQueue();
74
+ closed = false;
75
+ inlineErrorCallbacks = [];
76
+ constructor(call) {
77
+ this.call = call;
78
+ call.on('data', (chunk) => {
79
+ // Support both old format (chunk.envelope) and new oneof format (chunk.response.envelope)
80
+ const envelope = chunk?.response?.envelope ?? chunk?.envelope;
81
+ if (envelope) {
82
+ this.queue.push(envelope);
83
+ }
84
+ else if (chunk?.response?.error) {
85
+ // Inline application-level error — stream stays open
86
+ for (const cb of this.inlineErrorCallbacks)
87
+ cb(chunk.response.error);
88
+ }
89
+ });
90
+ call.on('error', (error) => {
91
+ this.queue.push(new errors_1.MacpTransportError(error.details || error.message));
92
+ });
93
+ call.on('end', () => {
94
+ this.queue.push(STREAM_END);
95
+ });
96
+ }
97
+ onInlineError(callback) {
98
+ this.inlineErrorCallbacks.push(callback);
99
+ }
100
+ send(envelope) {
101
+ if (this.closed)
102
+ return Promise.reject(new errors_1.MacpSdkError('stream is already closed'));
103
+ return new Promise((resolve, reject) => {
104
+ this.call.write({ envelope }, (error) => {
105
+ if (error)
106
+ reject(error);
107
+ else
108
+ resolve();
109
+ });
110
+ });
111
+ }
112
+ async *responses() {
113
+ while (true) {
114
+ const item = await this.queue.shift();
115
+ if (item === STREAM_END)
116
+ return;
117
+ if (item instanceof Error)
118
+ throw item;
119
+ yield item;
120
+ }
121
+ }
122
+ close() {
123
+ if (this.closed)
124
+ return;
125
+ this.closed = true;
126
+ this.call.end();
127
+ }
128
+ }
129
+ exports.MacpStream = MacpStream;
130
+ class MacpClient {
131
+ auth;
132
+ protoRegistry;
133
+ client;
134
+ secure;
135
+ defaultDeadlineMs;
136
+ clientName;
137
+ clientVersion;
138
+ constructor(options) {
139
+ this.auth = options.auth;
140
+ this.secure = options.secure ?? true;
141
+ if (!this.secure && options.allowInsecure !== true) {
142
+ throw new errors_1.MacpSdkError('MacpClient requires TLS. Pass secure: true (default) or, for local development only, ' +
143
+ 'both secure: false and allowInsecure: true. See RFC-MACP-0006 §3.');
144
+ }
145
+ this.defaultDeadlineMs = options.defaultDeadlineMs;
146
+ this.clientName = options.clientName ?? 'macp-sdk-typescript';
147
+ this.clientVersion = options.clientVersion ?? '0.2.0';
148
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
149
+ const { protoDir: defaultProtoDir } = require('@multiagentcoordinationprotocol/proto');
150
+ const protoDir = options.protoDir ?? defaultProtoDir;
151
+ this.protoRegistry = new proto_registry_1.ProtoRegistry(protoDir);
152
+ const packageDefinition = protoLoader.loadSync([
153
+ path.join(protoDir, 'macp/v1/core.proto'),
154
+ path.join(protoDir, 'macp/v1/envelope.proto'),
155
+ path.join(protoDir, 'macp/v1/policy.proto'),
156
+ ], {
157
+ keepCase: false,
158
+ longs: String,
159
+ enums: String,
160
+ defaults: true,
161
+ oneofs: true,
162
+ includeDirs: [protoDir],
163
+ });
164
+ const descriptor = grpc.loadPackageDefinition(packageDefinition);
165
+ const credentials = this.secure
166
+ ? grpc.credentials.createSsl(options.rootCertificates)
167
+ : grpc.credentials.createInsecure();
168
+ this.client = new descriptor.macp.v1.MACPRuntimeService(options.address, credentials);
169
+ }
170
+ requireAuth(auth) {
171
+ const selected = auth ?? this.auth;
172
+ if (!selected)
173
+ throw new errors_1.MacpSdkError('this operation requires auth; pass auth= or configure client.auth');
174
+ return selected;
175
+ }
176
+ metadata(auth) {
177
+ const selected = auth ?? this.auth;
178
+ if (!selected)
179
+ return undefined;
180
+ return (0, auth_1.metadataFromAuth)(selected);
181
+ }
182
+ deadline(deadlineMs) {
183
+ const resolved = deadlineMs ?? this.defaultDeadlineMs;
184
+ return resolved ? new Date(Date.now() + resolved) : undefined;
185
+ }
186
+ unary(method, request, auth, deadlineMs) {
187
+ return new Promise((resolve, reject) => {
188
+ const callback = (error, response) => {
189
+ if (error)
190
+ reject(new errors_1.MacpTransportError(error.details || error.message));
191
+ else
192
+ resolve(response);
193
+ };
194
+ const deadline = this.deadline(deadlineMs);
195
+ const metadata = this.metadata(auth);
196
+ if (metadata && deadline)
197
+ this.client[method](request, metadata, { deadline }, callback);
198
+ else if (metadata)
199
+ this.client[method](request, metadata, callback);
200
+ else if (deadline)
201
+ this.client[method](request, { deadline }, callback);
202
+ else
203
+ this.client[method](request, callback);
204
+ });
205
+ }
206
+ async initialize(deadlineMs) {
207
+ return this.unary('Initialize', {
208
+ supportedProtocolVersions: ['1.0'],
209
+ clientInfo: {
210
+ name: this.clientName,
211
+ title: this.clientName,
212
+ version: this.clientVersion,
213
+ description: 'TypeScript SDK for the MACP runtime',
214
+ websiteUrl: '',
215
+ },
216
+ capabilities: {
217
+ sessions: { stream: true },
218
+ cancellation: { cancelSession: true },
219
+ progress: { progress: true },
220
+ manifest: { getManifest: true },
221
+ modeRegistry: { listModes: true, listChanged: true },
222
+ roots: { listRoots: true, listChanged: true },
223
+ policyRegistry: { registerPolicy: true, listPolicies: true, listChanged: true },
224
+ experimental: { features: {} },
225
+ },
226
+ }, undefined, deadlineMs);
227
+ }
228
+ async send(envelope, options) {
229
+ const auth = this.requireAuth(options?.auth);
230
+ const response = await this.unary('Send', { envelope }, auth, options?.deadlineMs);
231
+ const ack = response.ack;
232
+ // Duplicate acks are success — the message was already accepted
233
+ if (ack?.duplicate)
234
+ return ack;
235
+ if (options?.raiseOnNack !== false && !ack?.ok)
236
+ throw new errors_1.MacpAckError(ack ?? {});
237
+ return ack;
238
+ }
239
+ async getSession(sessionId, options) {
240
+ const auth = this.requireAuth(options?.auth);
241
+ return this.unary('GetSession', { sessionId }, auth, options?.deadlineMs);
242
+ }
243
+ async cancelSession(sessionId, reason, options) {
244
+ const auth = this.requireAuth(options?.auth);
245
+ const request = { sessionId, reason };
246
+ if (options?.cancelledBy)
247
+ request.cancelledBy = options.cancelledBy;
248
+ const response = await this.unary('CancelSession', request, auth, options?.deadlineMs);
249
+ const ack = response.ack;
250
+ if (options?.raiseOnNack !== false && !ack?.ok)
251
+ throw new errors_1.MacpAckError(ack ?? {});
252
+ return ack;
253
+ }
254
+ async getManifest(agentId = '', deadlineMs) {
255
+ return this.unary('GetManifest', { agentId }, undefined, deadlineMs);
256
+ }
257
+ async listModes(deadlineMs) {
258
+ return this.unary('ListModes', {}, undefined, deadlineMs);
259
+ }
260
+ async listExtModes(deadlineMs) {
261
+ return this.unary('ListExtModes', {}, undefined, deadlineMs);
262
+ }
263
+ async listRoots(deadlineMs) {
264
+ return this.unary('ListRoots', {}, undefined, deadlineMs);
265
+ }
266
+ async registerExtMode(descriptor, options) {
267
+ const auth = this.requireAuth(options?.auth);
268
+ return this.unary('RegisterExtMode', { modeDescriptor: descriptor }, auth, options?.deadlineMs);
269
+ }
270
+ async unregisterExtMode(mode, options) {
271
+ const auth = this.requireAuth(options?.auth);
272
+ return this.unary('UnregisterExtMode', { mode }, auth, options?.deadlineMs);
273
+ }
274
+ async promoteMode(mode, promotedModeName = '', options) {
275
+ const auth = this.requireAuth(options?.auth);
276
+ return this.unary('PromoteMode', { mode, promotedModeName }, auth, options?.deadlineMs);
277
+ }
278
+ async registerPolicy(descriptor, options) {
279
+ const auth = this.requireAuth(options?.auth);
280
+ return this.unary('RegisterPolicy', { policyDescriptor: descriptor }, auth, options?.deadlineMs);
281
+ }
282
+ async unregisterPolicy(policyId, options) {
283
+ const auth = this.requireAuth(options?.auth);
284
+ return this.unary('UnregisterPolicy', { policyId }, auth, options?.deadlineMs);
285
+ }
286
+ async getPolicy(policyId, options) {
287
+ const auth = this.requireAuth(options?.auth);
288
+ const res = await this.unary('GetPolicy', { policyId }, auth, options?.deadlineMs);
289
+ return res.policyDescriptor;
290
+ }
291
+ async listPolicies(mode, options) {
292
+ const auth = this.requireAuth(options?.auth);
293
+ const res = await this.unary('ListPolicies', { mode: mode || '' }, auth, options?.deadlineMs);
294
+ return res.descriptors || [];
295
+ }
296
+ watchPolicies(auth) {
297
+ const metadata = this.metadata(auth);
298
+ return metadata ? this.client.WatchPolicies({}, metadata) : this.client.WatchPolicies({});
299
+ }
300
+ /** @deprecated Use {@link watchPolicies}. Scheduled for removal in 0.4.0. */
301
+ _watchPolicies(auth) {
302
+ return this.watchPolicies(auth);
303
+ }
304
+ openStream(options) {
305
+ const auth = this.requireAuth(options?.auth);
306
+ const metadata = this.metadata(auth);
307
+ const call = this.client.StreamSession(metadata);
308
+ return new MacpStream(call);
309
+ }
310
+ watchModeRegistry(auth) {
311
+ const metadata = this.metadata(auth);
312
+ return metadata ? this.client.WatchModeRegistry({}, metadata) : this.client.WatchModeRegistry({});
313
+ }
314
+ watchRoots(auth) {
315
+ const metadata = this.metadata(auth);
316
+ return metadata ? this.client.WatchRoots({}, metadata) : this.client.WatchRoots({});
317
+ }
318
+ watchSignals(auth) {
319
+ const metadata = this.metadata(auth);
320
+ return metadata ? this.client.WatchSignals({}, metadata) : this.client.WatchSignals({});
321
+ }
322
+ /**
323
+ * @deprecated Use {@link watchModeRegistry}, {@link watchRoots},
324
+ * {@link watchSignals}. Scheduled for removal in 0.4.0 — the underscored
325
+ * aliases were kept while `src/watchers.ts` migrated.
326
+ */
327
+ _watchModeRegistry(auth) {
328
+ return this.watchModeRegistry(auth);
329
+ }
330
+ /** @deprecated Use {@link watchRoots}. Scheduled for removal in 0.4.0. */
331
+ _watchRoots(auth) {
332
+ return this.watchRoots(auth);
333
+ }
334
+ /** @deprecated Use {@link watchSignals}. Scheduled for removal in 0.4.0. */
335
+ _watchSignals(auth) {
336
+ return this.watchSignals(auth);
337
+ }
338
+ async sendSignal(options) {
339
+ (0, validation_1.validateSignalType)(options.signalType, options.data);
340
+ const auth = this.requireAuth(options.auth);
341
+ (0, auth_1.assertSenderMatchesIdentity)(auth, options.sender);
342
+ const payload = this.protoRegistry.encodeKnownPayload('', 'Signal', {
343
+ signalType: options.signalType,
344
+ data: options.data ?? Buffer.alloc(0),
345
+ confidence: options.confidence ?? 0,
346
+ correlationSessionId: options.correlationSessionId ?? '',
347
+ });
348
+ const envelope = (0, envelope_1.buildEnvelope)({
349
+ mode: '',
350
+ messageType: 'Signal',
351
+ sessionId: '',
352
+ sender: options.sender ?? this.senderHint(auth) ?? '',
353
+ payload,
354
+ });
355
+ return this.send(envelope, { auth, deadlineMs: options.deadlineMs });
356
+ }
357
+ async sendProgress(options) {
358
+ const auth = this.requireAuth(options.auth);
359
+ (0, auth_1.assertSenderMatchesIdentity)(auth, options.sender);
360
+ const payload = this.protoRegistry.encodeKnownPayload('', 'Progress', {
361
+ progressToken: options.progressToken,
362
+ progress: options.progress,
363
+ total: options.total,
364
+ message: options.message ?? '',
365
+ targetMessageId: options.targetMessageId ?? '',
366
+ });
367
+ const envelope = (0, envelope_1.buildEnvelope)({
368
+ mode: options.mode ?? '',
369
+ messageType: 'Progress',
370
+ sessionId: options.sessionId ?? '',
371
+ sender: options.sender ?? this.senderHint(auth) ?? '',
372
+ payload,
373
+ });
374
+ return this.send(envelope, { auth, deadlineMs: options.deadlineMs });
375
+ }
376
+ senderHint(auth) {
377
+ return (0, auth_1.authSender)(auth ?? this.auth);
378
+ }
379
+ close() {
380
+ if (typeof this.client.close === 'function')
381
+ this.client.close();
382
+ }
383
+ }
384
+ exports.MacpClient = MacpClient;
@@ -0,0 +1,26 @@
1
+ export declare const MACP_VERSION = "1.0";
2
+ export declare const DEFAULT_MODE_VERSION = "1.0.0";
3
+ export declare const DEFAULT_CONFIGURATION_VERSION = "config.default";
4
+ export declare const DEFAULT_POLICY_VERSION = "policy.default";
5
+ export declare const MODE_DECISION = "macp.mode.decision.v1";
6
+ export declare const MODE_PROPOSAL = "macp.mode.proposal.v1";
7
+ export declare const MODE_TASK = "macp.mode.task.v1";
8
+ export declare const MODE_HANDOFF = "macp.mode.handoff.v1";
9
+ export declare const MODE_QUORUM = "macp.mode.quorum.v1";
10
+ export declare const MODE_MULTI_ROUND = "ext.multi_round.v1";
11
+ export declare const ERR_UNSUPPORTED_PROTOCOL_VERSION = "UNSUPPORTED_PROTOCOL_VERSION";
12
+ export declare const ERR_INVALID_ENVELOPE = "INVALID_ENVELOPE";
13
+ export declare const ERR_SESSION_ALREADY_EXISTS = "SESSION_ALREADY_EXISTS";
14
+ export declare const ERR_SESSION_NOT_FOUND = "SESSION_NOT_FOUND";
15
+ export declare const ERR_SESSION_NOT_OPEN = "SESSION_NOT_OPEN";
16
+ export declare const ERR_MODE_NOT_SUPPORTED = "MODE_NOT_SUPPORTED";
17
+ export declare const ERR_FORBIDDEN = "FORBIDDEN";
18
+ export declare const ERR_UNAUTHENTICATED = "UNAUTHENTICATED";
19
+ export declare const ERR_DUPLICATE_MESSAGE = "DUPLICATE_MESSAGE";
20
+ export declare const ERR_PAYLOAD_TOO_LARGE = "PAYLOAD_TOO_LARGE";
21
+ export declare const ERR_RATE_LIMITED = "RATE_LIMITED";
22
+ export declare const ERR_INTERNAL_ERROR = "INTERNAL_ERROR";
23
+ export declare const ERR_POLICY_DENIED = "POLICY_DENIED";
24
+ export declare const ERR_INVALID_SESSION_ID = "INVALID_SESSION_ID";
25
+ export declare const ERR_UNKNOWN_POLICY_VERSION = "UNKNOWN_POLICY_VERSION";
26
+ export declare const ERR_INVALID_POLICY_DEFINITION = "INVALID_POLICY_DEFINITION";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ERR_INVALID_POLICY_DEFINITION = exports.ERR_UNKNOWN_POLICY_VERSION = exports.ERR_INVALID_SESSION_ID = exports.ERR_POLICY_DENIED = exports.ERR_INTERNAL_ERROR = exports.ERR_RATE_LIMITED = exports.ERR_PAYLOAD_TOO_LARGE = exports.ERR_DUPLICATE_MESSAGE = exports.ERR_UNAUTHENTICATED = exports.ERR_FORBIDDEN = exports.ERR_MODE_NOT_SUPPORTED = exports.ERR_SESSION_NOT_OPEN = exports.ERR_SESSION_NOT_FOUND = exports.ERR_SESSION_ALREADY_EXISTS = exports.ERR_INVALID_ENVELOPE = exports.ERR_UNSUPPORTED_PROTOCOL_VERSION = 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
+ exports.MACP_VERSION = '1.0';
5
+ exports.DEFAULT_MODE_VERSION = '1.0.0';
6
+ exports.DEFAULT_CONFIGURATION_VERSION = 'config.default';
7
+ exports.DEFAULT_POLICY_VERSION = 'policy.default';
8
+ exports.MODE_DECISION = 'macp.mode.decision.v1';
9
+ exports.MODE_PROPOSAL = 'macp.mode.proposal.v1';
10
+ exports.MODE_TASK = 'macp.mode.task.v1';
11
+ exports.MODE_HANDOFF = 'macp.mode.handoff.v1';
12
+ exports.MODE_QUORUM = 'macp.mode.quorum.v1';
13
+ exports.MODE_MULTI_ROUND = 'ext.multi_round.v1';
14
+ exports.ERR_UNSUPPORTED_PROTOCOL_VERSION = 'UNSUPPORTED_PROTOCOL_VERSION';
15
+ exports.ERR_INVALID_ENVELOPE = 'INVALID_ENVELOPE';
16
+ exports.ERR_SESSION_ALREADY_EXISTS = 'SESSION_ALREADY_EXISTS';
17
+ exports.ERR_SESSION_NOT_FOUND = 'SESSION_NOT_FOUND';
18
+ exports.ERR_SESSION_NOT_OPEN = 'SESSION_NOT_OPEN';
19
+ exports.ERR_MODE_NOT_SUPPORTED = 'MODE_NOT_SUPPORTED';
20
+ exports.ERR_FORBIDDEN = 'FORBIDDEN';
21
+ exports.ERR_UNAUTHENTICATED = 'UNAUTHENTICATED';
22
+ exports.ERR_DUPLICATE_MESSAGE = 'DUPLICATE_MESSAGE';
23
+ exports.ERR_PAYLOAD_TOO_LARGE = 'PAYLOAD_TOO_LARGE';
24
+ exports.ERR_RATE_LIMITED = 'RATE_LIMITED';
25
+ exports.ERR_INTERNAL_ERROR = 'INTERNAL_ERROR';
26
+ exports.ERR_POLICY_DENIED = 'POLICY_DENIED';
27
+ exports.ERR_INVALID_SESSION_ID = 'INVALID_SESSION_ID';
28
+ exports.ERR_UNKNOWN_POLICY_VERSION = 'UNKNOWN_POLICY_VERSION';
29
+ exports.ERR_INVALID_POLICY_DEFINITION = 'INVALID_POLICY_DEFINITION';
@@ -0,0 +1,65 @@
1
+ import { type AuthConfig } from './auth';
2
+ import type { MacpClient, MacpStream } from './client';
3
+ import { DecisionProjection } from './projections';
4
+ import type { Ack, DecisionEvaluationPayload, DecisionObjectionPayload, DecisionProposalPayload, DecisionVotePayload, SessionMetadata } from './types';
5
+ interface DecisionSessionOptions {
6
+ sessionId?: string;
7
+ modeVersion?: string;
8
+ configurationVersion?: string;
9
+ policyVersion?: string;
10
+ auth?: AuthConfig;
11
+ }
12
+ export declare class DecisionSession {
13
+ readonly client: MacpClient;
14
+ readonly sessionId: string;
15
+ readonly modeVersion: string;
16
+ readonly configurationVersion: string;
17
+ readonly policyVersion: string;
18
+ readonly auth?: AuthConfig;
19
+ readonly projection: DecisionProjection;
20
+ constructor(client: MacpClient, options?: DecisionSessionOptions);
21
+ private senderFor;
22
+ private sendAndTrack;
23
+ start(input: {
24
+ intent: string;
25
+ participants: string[];
26
+ ttlMs: number;
27
+ context?: Buffer | string | Record<string, unknown>;
28
+ roots?: {
29
+ uri: string;
30
+ name?: string;
31
+ }[];
32
+ sender?: string;
33
+ }): Promise<Ack>;
34
+ propose(input: DecisionProposalPayload & {
35
+ sender?: string;
36
+ auth?: AuthConfig;
37
+ }): Promise<Ack>;
38
+ evaluate(input: DecisionEvaluationPayload & {
39
+ sender?: string;
40
+ auth?: AuthConfig;
41
+ }): Promise<Ack>;
42
+ raiseObjection(input: DecisionObjectionPayload & {
43
+ sender?: string;
44
+ auth?: AuthConfig;
45
+ }): Promise<Ack>;
46
+ vote(input: DecisionVotePayload & {
47
+ sender?: string;
48
+ auth?: AuthConfig;
49
+ }): Promise<Ack>;
50
+ commit(input: {
51
+ action: string;
52
+ authorityScope: string;
53
+ reason: string;
54
+ commitmentId?: string;
55
+ outcomePositive?: boolean;
56
+ sender?: string;
57
+ auth?: AuthConfig;
58
+ }): Promise<Ack>;
59
+ metadata(auth?: AuthConfig): Promise<{
60
+ metadata: SessionMetadata;
61
+ }>;
62
+ cancel(reason?: string, auth?: AuthConfig): Promise<Ack>;
63
+ openStream(auth?: AuthConfig): MacpStream;
64
+ }
65
+ export {};
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DecisionSession = void 0;
4
+ const auth_1 = require("./auth");
5
+ const constants_1 = require("./constants");
6
+ const envelope_1 = require("./envelope");
7
+ const projections_1 = require("./projections");
8
+ const validation_1 = require("./validation");
9
+ class DecisionSession {
10
+ client;
11
+ sessionId;
12
+ modeVersion;
13
+ configurationVersion;
14
+ policyVersion;
15
+ auth;
16
+ projection = new projections_1.DecisionProjection();
17
+ constructor(client, options = {}) {
18
+ this.client = client;
19
+ if (options.sessionId)
20
+ (0, validation_1.validateSessionId)(options.sessionId);
21
+ this.sessionId = options.sessionId ?? (0, envelope_1.newSessionId)();
22
+ this.modeVersion = options.modeVersion ?? constants_1.DEFAULT_MODE_VERSION;
23
+ this.configurationVersion = options.configurationVersion ?? constants_1.DEFAULT_CONFIGURATION_VERSION;
24
+ this.policyVersion = options.policyVersion ?? constants_1.DEFAULT_POLICY_VERSION;
25
+ this.auth = options.auth;
26
+ }
27
+ senderFor(sender, auth) {
28
+ const effectiveAuth = auth ?? this.auth ?? this.client.auth;
29
+ (0, auth_1.assertSenderMatchesIdentity)(effectiveAuth, sender);
30
+ return sender ?? (0, auth_1.authSender)(effectiveAuth) ?? '';
31
+ }
32
+ async sendAndTrack(envelope, auth) {
33
+ const ack = await this.client.send(envelope, { auth: auth ?? this.auth });
34
+ if (ack.ok)
35
+ this.projection.applyEnvelope(envelope, this.client.protoRegistry);
36
+ return ack;
37
+ }
38
+ async start(input) {
39
+ (0, validation_1.validateSessionStart)({
40
+ intent: input.intent,
41
+ participants: input.participants,
42
+ ttlMs: input.ttlMs,
43
+ modeVersion: this.modeVersion,
44
+ configurationVersion: this.configurationVersion,
45
+ });
46
+ const payload = (0, envelope_1.buildSessionStartPayload)({
47
+ intent: input.intent,
48
+ participants: input.participants,
49
+ ttlMs: input.ttlMs,
50
+ context: input.context,
51
+ roots: input.roots,
52
+ modeVersion: this.modeVersion,
53
+ configurationVersion: this.configurationVersion,
54
+ policyVersion: this.policyVersion,
55
+ });
56
+ const envelope = (0, envelope_1.buildEnvelope)({
57
+ mode: constants_1.MODE_DECISION,
58
+ messageType: 'SessionStart',
59
+ sessionId: this.sessionId,
60
+ sender: this.senderFor(input.sender),
61
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_DECISION, 'SessionStart', (0, envelope_1.toProtoPayload)(payload)),
62
+ });
63
+ return this.sendAndTrack(envelope, this.auth);
64
+ }
65
+ async propose(input) {
66
+ (0, validation_1.validateRequiredField)('proposalId', input.proposalId);
67
+ (0, validation_1.validateRequiredField)('option', input.option);
68
+ const envelope = (0, envelope_1.buildEnvelope)({
69
+ mode: constants_1.MODE_DECISION,
70
+ messageType: 'Proposal',
71
+ sessionId: this.sessionId,
72
+ sender: this.senderFor(input.sender, input.auth),
73
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_DECISION, 'Proposal', (0, envelope_1.toProtoPayload)(input)),
74
+ });
75
+ return this.sendAndTrack(envelope, input.auth);
76
+ }
77
+ async evaluate(input) {
78
+ (0, validation_1.validateRequiredField)('proposalId', input.proposalId);
79
+ (0, validation_1.validateRecommendation)(input.recommendation);
80
+ (0, validation_1.validateConfidence)(input.confidence);
81
+ const envelope = (0, envelope_1.buildEnvelope)({
82
+ mode: constants_1.MODE_DECISION,
83
+ messageType: 'Evaluation',
84
+ sessionId: this.sessionId,
85
+ sender: this.senderFor(input.sender, input.auth),
86
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_DECISION, 'Evaluation', (0, envelope_1.toProtoPayload)(input)),
87
+ });
88
+ return this.sendAndTrack(envelope, input.auth);
89
+ }
90
+ async raiseObjection(input) {
91
+ (0, validation_1.validateRequiredField)('proposalId', input.proposalId);
92
+ if (input.severity)
93
+ (0, validation_1.validateSeverity)(input.severity);
94
+ const envelope = (0, envelope_1.buildEnvelope)({
95
+ mode: constants_1.MODE_DECISION,
96
+ messageType: 'Objection',
97
+ sessionId: this.sessionId,
98
+ sender: this.senderFor(input.sender, input.auth),
99
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_DECISION, 'Objection', (0, envelope_1.toProtoPayload)(input)),
100
+ });
101
+ return this.sendAndTrack(envelope, input.auth);
102
+ }
103
+ async vote(input) {
104
+ (0, validation_1.validateRequiredField)('proposalId', input.proposalId);
105
+ (0, validation_1.validateVote)(input.vote);
106
+ const envelope = (0, envelope_1.buildEnvelope)({
107
+ mode: constants_1.MODE_DECISION,
108
+ messageType: 'Vote',
109
+ sessionId: this.sessionId,
110
+ sender: this.senderFor(input.sender, input.auth),
111
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_DECISION, 'Vote', (0, envelope_1.toProtoPayload)(input)),
112
+ });
113
+ return this.sendAndTrack(envelope, input.auth);
114
+ }
115
+ async commit(input) {
116
+ const payload = (0, envelope_1.buildCommitmentPayload)({
117
+ action: input.action,
118
+ authorityScope: input.authorityScope,
119
+ reason: input.reason,
120
+ commitmentId: input.commitmentId,
121
+ outcomePositive: input.outcomePositive,
122
+ modeVersion: this.modeVersion,
123
+ configurationVersion: this.configurationVersion,
124
+ policyVersion: this.policyVersion,
125
+ });
126
+ const envelope = (0, envelope_1.buildEnvelope)({
127
+ mode: constants_1.MODE_DECISION,
128
+ messageType: 'Commitment',
129
+ sessionId: this.sessionId,
130
+ sender: this.senderFor(input.sender, input.auth),
131
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_DECISION, 'Commitment', (0, envelope_1.toProtoPayload)(payload)),
132
+ });
133
+ return this.sendAndTrack(envelope, input.auth);
134
+ }
135
+ metadata(auth) {
136
+ return this.client.getSession(this.sessionId, { auth: auth ?? this.auth });
137
+ }
138
+ async cancel(reason = '', auth) {
139
+ return this.client.cancelSession(this.sessionId, reason, {
140
+ auth: auth ?? this.auth,
141
+ raiseOnNack: true,
142
+ });
143
+ }
144
+ openStream(auth) {
145
+ return this.client.openStream({ auth: auth ?? this.auth });
146
+ }
147
+ }
148
+ exports.DecisionSession = DecisionSession;