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
@@ -0,0 +1,165 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ProtoRegistry = void 0;
40
+ const path = __importStar(require("node:path"));
41
+ const protobufjs_1 = __importDefault(require("protobufjs"));
42
+ const constants_1 = require("./constants");
43
+ const CORE_MAP = {
44
+ SessionStart: 'macp.v1.SessionStartPayload',
45
+ Commitment: 'macp.v1.CommitmentPayload',
46
+ Signal: 'macp.v1.SignalPayload',
47
+ Progress: 'macp.v1.ProgressPayload',
48
+ };
49
+ const MODE_MAP = {
50
+ [constants_1.MODE_DECISION]: {
51
+ Proposal: 'macp.modes.decision.v1.ProposalPayload',
52
+ Evaluation: 'macp.modes.decision.v1.EvaluationPayload',
53
+ Objection: 'macp.modes.decision.v1.ObjectionPayload',
54
+ Vote: 'macp.modes.decision.v1.VotePayload',
55
+ },
56
+ [constants_1.MODE_PROPOSAL]: {
57
+ Proposal: 'macp.modes.proposal.v1.ProposalPayload',
58
+ CounterProposal: 'macp.modes.proposal.v1.CounterProposalPayload',
59
+ Accept: 'macp.modes.proposal.v1.AcceptPayload',
60
+ Reject: 'macp.modes.proposal.v1.RejectPayload',
61
+ Withdraw: 'macp.modes.proposal.v1.WithdrawPayload',
62
+ },
63
+ [constants_1.MODE_TASK]: {
64
+ TaskRequest: 'macp.modes.task.v1.TaskRequestPayload',
65
+ TaskAccept: 'macp.modes.task.v1.TaskAcceptPayload',
66
+ TaskReject: 'macp.modes.task.v1.TaskRejectPayload',
67
+ TaskUpdate: 'macp.modes.task.v1.TaskUpdatePayload',
68
+ TaskComplete: 'macp.modes.task.v1.TaskCompletePayload',
69
+ TaskFail: 'macp.modes.task.v1.TaskFailPayload',
70
+ },
71
+ [constants_1.MODE_HANDOFF]: {
72
+ HandoffOffer: 'macp.modes.handoff.v1.HandoffOfferPayload',
73
+ HandoffContext: 'macp.modes.handoff.v1.HandoffContextPayload',
74
+ HandoffAccept: 'macp.modes.handoff.v1.HandoffAcceptPayload',
75
+ HandoffDecline: 'macp.modes.handoff.v1.HandoffDeclinePayload',
76
+ },
77
+ [constants_1.MODE_QUORUM]: {
78
+ ApprovalRequest: 'macp.modes.quorum.v1.ApprovalRequestPayload',
79
+ Approve: 'macp.modes.quorum.v1.ApprovePayload',
80
+ Reject: 'macp.modes.quorum.v1.RejectPayload',
81
+ Abstain: 'macp.modes.quorum.v1.AbstainPayload',
82
+ },
83
+ [constants_1.MODE_MULTI_ROUND]: {
84
+ Contribute: '__json__',
85
+ },
86
+ };
87
+ const PROTO_FILES = [
88
+ 'macp/v1/core.proto',
89
+ 'macp/v1/envelope.proto',
90
+ 'macp/v1/policy.proto',
91
+ 'macp/modes/decision/v1/decision.proto',
92
+ 'macp/modes/proposal/v1/proposal.proto',
93
+ 'macp/modes/task/v1/task.proto',
94
+ 'macp/modes/handoff/v1/handoff.proto',
95
+ 'macp/modes/quorum/v1/quorum.proto',
96
+ ];
97
+ class ProtoRegistry {
98
+ protoDir;
99
+ root;
100
+ constructor(protoDir) {
101
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
102
+ const { protoDir: defaultProtoDir } = require('@multiagentcoordinationprotocol/proto');
103
+ this.protoDir = path.resolve(protoDir ?? defaultProtoDir);
104
+ this.root = new protobufjs_1.default.Root();
105
+ this.root.resolvePath = (_origin, target) => {
106
+ if (path.isAbsolute(target))
107
+ return target;
108
+ return path.join(this.protoDir, target);
109
+ };
110
+ this.root.loadSync(PROTO_FILES.map((file) => path.join(this.protoDir, file)));
111
+ this.root.resolveAll();
112
+ }
113
+ getKnownTypeName(mode, messageType) {
114
+ return MODE_MAP[mode]?.[messageType] ?? CORE_MAP[messageType];
115
+ }
116
+ encodeMessage(typeName, value) {
117
+ const type = this.lookupType(typeName);
118
+ const message = type.fromObject(value);
119
+ return Buffer.from(type.encode(message).finish());
120
+ }
121
+ decodeMessage(typeName, payload) {
122
+ const type = this.lookupType(typeName);
123
+ const decoded = type.decode(payload);
124
+ return type.toObject(decoded, {
125
+ longs: String,
126
+ enums: String,
127
+ bytes: Buffer,
128
+ defaults: false,
129
+ });
130
+ }
131
+ encodeKnownPayload(mode, messageType, value) {
132
+ const typeName = this.getKnownTypeName(mode, messageType);
133
+ if (!typeName)
134
+ throw new Error(`unknown payload mapping for ${mode}/${messageType}`);
135
+ if (typeName === '__json__')
136
+ return Buffer.from(JSON.stringify(value), 'utf8');
137
+ return this.encodeMessage(typeName, value);
138
+ }
139
+ decodeKnownPayload(mode, messageType, payload) {
140
+ const typeName = this.getKnownTypeName(mode, messageType);
141
+ if (!typeName)
142
+ return this.tryDecodeUtf8(payload);
143
+ if (typeName === '__json__')
144
+ return this.tryDecodeUtf8(payload);
145
+ return this.decodeMessage(typeName, payload);
146
+ }
147
+ lookupType(typeName) {
148
+ const lookedUp = this.root.lookupType(typeName);
149
+ if (!(lookedUp instanceof protobufjs_1.default.Type))
150
+ throw new Error(`protobuf type '${typeName}' not found`);
151
+ return lookedUp;
152
+ }
153
+ tryDecodeUtf8(payload) {
154
+ if (!payload.length)
155
+ return undefined;
156
+ const text = payload.toString('utf8');
157
+ try {
158
+ return { encoding: 'json', json: JSON.parse(text) };
159
+ }
160
+ catch {
161
+ return { encoding: 'text', text, payloadBase64: payload.toString('base64') };
162
+ }
163
+ }
164
+ }
165
+ exports.ProtoRegistry = ProtoRegistry;
@@ -0,0 +1,65 @@
1
+ import { type AuthConfig } from './auth';
2
+ import type { MacpClient, MacpStream } from './client';
3
+ import { QuorumProjection } from './projections/quorum';
4
+ import type { AbstainPayload, Ack, ApprovalRequestPayload, ApprovePayload, QuorumRejectPayload, SessionMetadata } from './types';
5
+ interface QuorumSessionOptions {
6
+ sessionId?: string;
7
+ modeVersion?: string;
8
+ configurationVersion?: string;
9
+ policyVersion?: string;
10
+ auth?: AuthConfig;
11
+ }
12
+ export declare class QuorumSession {
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: QuorumProjection;
20
+ constructor(client: MacpClient, options?: QuorumSessionOptions);
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
+ requestApproval(input: ApprovalRequestPayload & {
35
+ sender?: string;
36
+ auth?: AuthConfig;
37
+ }): Promise<Ack>;
38
+ approve(input: ApprovePayload & {
39
+ sender?: string;
40
+ auth?: AuthConfig;
41
+ }): Promise<Ack>;
42
+ reject(input: QuorumRejectPayload & {
43
+ sender?: string;
44
+ auth?: AuthConfig;
45
+ }): Promise<Ack>;
46
+ abstain(input: AbstainPayload & {
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 {};
package/dist/quorum.js ADDED
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuorumSession = void 0;
4
+ const auth_1 = require("./auth");
5
+ const constants_1 = require("./constants");
6
+ const envelope_1 = require("./envelope");
7
+ const quorum_1 = require("./projections/quorum");
8
+ const validation_1 = require("./validation");
9
+ class QuorumSession {
10
+ client;
11
+ sessionId;
12
+ modeVersion;
13
+ configurationVersion;
14
+ policyVersion;
15
+ auth;
16
+ projection = new quorum_1.QuorumProjection();
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_QUORUM,
58
+ messageType: 'SessionStart',
59
+ sessionId: this.sessionId,
60
+ sender: this.senderFor(input.sender),
61
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_QUORUM, 'SessionStart', (0, envelope_1.toProtoPayload)(payload)),
62
+ });
63
+ return this.sendAndTrack(envelope, this.auth);
64
+ }
65
+ async requestApproval(input) {
66
+ (0, validation_1.validateRequiredField)('requestId', input.requestId);
67
+ (0, validation_1.validateRequiredField)('action', input.action);
68
+ (0, validation_1.validateRequiredField)('summary', input.summary);
69
+ const envelope = (0, envelope_1.buildEnvelope)({
70
+ mode: constants_1.MODE_QUORUM,
71
+ messageType: 'ApprovalRequest',
72
+ sessionId: this.sessionId,
73
+ sender: this.senderFor(input.sender, input.auth),
74
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_QUORUM, 'ApprovalRequest', (0, envelope_1.toProtoPayload)(input)),
75
+ });
76
+ return this.sendAndTrack(envelope, input.auth);
77
+ }
78
+ async approve(input) {
79
+ (0, validation_1.validateRequiredField)('requestId', input.requestId);
80
+ const envelope = (0, envelope_1.buildEnvelope)({
81
+ mode: constants_1.MODE_QUORUM,
82
+ messageType: 'Approve',
83
+ sessionId: this.sessionId,
84
+ sender: this.senderFor(input.sender, input.auth),
85
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_QUORUM, 'Approve', (0, envelope_1.toProtoPayload)(input)),
86
+ });
87
+ return this.sendAndTrack(envelope, input.auth);
88
+ }
89
+ async reject(input) {
90
+ (0, validation_1.validateRequiredField)('requestId', input.requestId);
91
+ const envelope = (0, envelope_1.buildEnvelope)({
92
+ mode: constants_1.MODE_QUORUM,
93
+ messageType: 'Reject',
94
+ sessionId: this.sessionId,
95
+ sender: this.senderFor(input.sender, input.auth),
96
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_QUORUM, 'Reject', (0, envelope_1.toProtoPayload)(input)),
97
+ });
98
+ return this.sendAndTrack(envelope, input.auth);
99
+ }
100
+ async abstain(input) {
101
+ (0, validation_1.validateRequiredField)('requestId', input.requestId);
102
+ const envelope = (0, envelope_1.buildEnvelope)({
103
+ mode: constants_1.MODE_QUORUM,
104
+ messageType: 'Abstain',
105
+ sessionId: this.sessionId,
106
+ sender: this.senderFor(input.sender, input.auth),
107
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_QUORUM, 'Abstain', (0, envelope_1.toProtoPayload)(input)),
108
+ });
109
+ return this.sendAndTrack(envelope, input.auth);
110
+ }
111
+ async commit(input) {
112
+ const payload = (0, envelope_1.buildCommitmentPayload)({
113
+ action: input.action,
114
+ authorityScope: input.authorityScope,
115
+ reason: input.reason,
116
+ commitmentId: input.commitmentId,
117
+ outcomePositive: input.outcomePositive,
118
+ modeVersion: this.modeVersion,
119
+ configurationVersion: this.configurationVersion,
120
+ policyVersion: this.policyVersion,
121
+ });
122
+ const envelope = (0, envelope_1.buildEnvelope)({
123
+ mode: constants_1.MODE_QUORUM,
124
+ messageType: 'Commitment',
125
+ sessionId: this.sessionId,
126
+ sender: this.senderFor(input.sender, input.auth),
127
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_QUORUM, 'Commitment', (0, envelope_1.toProtoPayload)(payload)),
128
+ });
129
+ return this.sendAndTrack(envelope, input.auth);
130
+ }
131
+ metadata(auth) {
132
+ return this.client.getSession(this.sessionId, { auth: auth ?? this.auth });
133
+ }
134
+ async cancel(reason = '', auth) {
135
+ return this.client.cancelSession(this.sessionId, reason, {
136
+ auth: auth ?? this.auth,
137
+ raiseOnNack: true,
138
+ });
139
+ }
140
+ openStream(auth) {
141
+ return this.client.openStream({ auth: auth ?? this.auth });
142
+ }
143
+ }
144
+ exports.QuorumSession = QuorumSession;
@@ -0,0 +1,14 @@
1
+ import type { AuthConfig } from './auth';
2
+ import type { MacpClient } from './client';
3
+ import type { Ack, Envelope } from './types';
4
+ export interface RetryPolicy {
5
+ maxRetries: number;
6
+ backoffBase: number;
7
+ backoffMax: number;
8
+ retryableCodes: Set<string>;
9
+ }
10
+ export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
11
+ export declare function retrySend(client: MacpClient, envelope: Envelope, options?: {
12
+ policy?: Partial<RetryPolicy>;
13
+ auth?: AuthConfig;
14
+ }): Promise<Ack>;
package/dist/retry.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_RETRY_POLICY = void 0;
4
+ exports.retrySend = retrySend;
5
+ const errors_1 = require("./errors");
6
+ exports.DEFAULT_RETRY_POLICY = {
7
+ maxRetries: 3,
8
+ backoffBase: 0.1,
9
+ backoffMax: 2.0,
10
+ retryableCodes: new Set(['RATE_LIMITED', 'INTERNAL_ERROR']),
11
+ };
12
+ function sleep(seconds) {
13
+ return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
14
+ }
15
+ async function retrySend(client, envelope, options) {
16
+ const policy = {
17
+ ...exports.DEFAULT_RETRY_POLICY,
18
+ ...options?.policy,
19
+ };
20
+ let lastError;
21
+ for (let attempt = 0; attempt <= policy.maxRetries; attempt++) {
22
+ try {
23
+ return await client.send(envelope, { auth: options?.auth, raiseOnNack: true });
24
+ }
25
+ catch (err) {
26
+ if (err instanceof errors_1.MacpTransportError) {
27
+ lastError = err;
28
+ }
29
+ else if (err instanceof errors_1.MacpAckError) {
30
+ if (!policy.retryableCodes.has(err.ack.error?.code ?? '')) {
31
+ throw err;
32
+ }
33
+ lastError = err;
34
+ }
35
+ else {
36
+ throw err;
37
+ }
38
+ }
39
+ if (attempt < policy.maxRetries) {
40
+ const delay = Math.min(policy.backoffBase * 2 ** attempt, policy.backoffMax);
41
+ await sleep(delay);
42
+ }
43
+ }
44
+ const error = new errors_1.MacpRetryError(`retries exhausted after ${policy.maxRetries} attempts`);
45
+ if (lastError)
46
+ error.cause = lastError;
47
+ throw error;
48
+ }
package/dist/task.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ import { type AuthConfig } from './auth';
2
+ import type { MacpClient, MacpStream } from './client';
3
+ import { TaskProjection } from './projections/task';
4
+ import type { Ack, SessionMetadata, TaskAcceptPayload, TaskCompletePayload, TaskFailPayload, TaskRejectPayload, TaskRequestPayload, TaskUpdatePayload } from './types';
5
+ interface TaskSessionOptions {
6
+ sessionId?: string;
7
+ modeVersion?: string;
8
+ configurationVersion?: string;
9
+ policyVersion?: string;
10
+ auth?: AuthConfig;
11
+ }
12
+ export declare class TaskSession {
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: TaskProjection;
20
+ constructor(client: MacpClient, options?: TaskSessionOptions);
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
+ request(input: TaskRequestPayload & {
35
+ sender?: string;
36
+ auth?: AuthConfig;
37
+ }): Promise<Ack>;
38
+ acceptTask(input: TaskAcceptPayload & {
39
+ sender?: string;
40
+ auth?: AuthConfig;
41
+ }): Promise<Ack>;
42
+ rejectTask(input: TaskRejectPayload & {
43
+ sender?: string;
44
+ auth?: AuthConfig;
45
+ }): Promise<Ack>;
46
+ update(input: TaskUpdatePayload & {
47
+ sender?: string;
48
+ auth?: AuthConfig;
49
+ }): Promise<Ack>;
50
+ complete(input: TaskCompletePayload & {
51
+ sender?: string;
52
+ auth?: AuthConfig;
53
+ }): Promise<Ack>;
54
+ fail(input: TaskFailPayload & {
55
+ sender?: string;
56
+ auth?: AuthConfig;
57
+ }): Promise<Ack>;
58
+ commit(input: {
59
+ action: string;
60
+ authorityScope: string;
61
+ reason: string;
62
+ commitmentId?: string;
63
+ outcomePositive?: boolean;
64
+ sender?: string;
65
+ auth?: AuthConfig;
66
+ }): Promise<Ack>;
67
+ metadata(auth?: AuthConfig): Promise<{
68
+ metadata: SessionMetadata;
69
+ }>;
70
+ cancel(reason?: string, auth?: AuthConfig): Promise<Ack>;
71
+ openStream(auth?: AuthConfig): MacpStream;
72
+ }
73
+ export {};
package/dist/task.js ADDED
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TaskSession = void 0;
4
+ const auth_1 = require("./auth");
5
+ const constants_1 = require("./constants");
6
+ const envelope_1 = require("./envelope");
7
+ const task_1 = require("./projections/task");
8
+ const validation_1 = require("./validation");
9
+ class TaskSession {
10
+ client;
11
+ sessionId;
12
+ modeVersion;
13
+ configurationVersion;
14
+ policyVersion;
15
+ auth;
16
+ projection = new task_1.TaskProjection();
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_TASK,
58
+ messageType: 'SessionStart',
59
+ sessionId: this.sessionId,
60
+ sender: this.senderFor(input.sender),
61
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'SessionStart', (0, envelope_1.toProtoPayload)(payload)),
62
+ });
63
+ return this.sendAndTrack(envelope, this.auth);
64
+ }
65
+ async request(input) {
66
+ (0, validation_1.validateRequiredField)('taskId', input.taskId);
67
+ (0, validation_1.validateRequiredField)('title', input.title);
68
+ (0, validation_1.validateRequiredField)('instructions', input.instructions);
69
+ const envelope = (0, envelope_1.buildEnvelope)({
70
+ mode: constants_1.MODE_TASK,
71
+ messageType: 'TaskRequest',
72
+ sessionId: this.sessionId,
73
+ sender: this.senderFor(input.sender, input.auth),
74
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'TaskRequest', (0, envelope_1.toProtoPayload)(input)),
75
+ });
76
+ return this.sendAndTrack(envelope, input.auth);
77
+ }
78
+ async acceptTask(input) {
79
+ (0, validation_1.validateRequiredField)('taskId', input.taskId);
80
+ const envelope = (0, envelope_1.buildEnvelope)({
81
+ mode: constants_1.MODE_TASK,
82
+ messageType: 'TaskAccept',
83
+ sessionId: this.sessionId,
84
+ sender: this.senderFor(input.sender, input.auth),
85
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'TaskAccept', (0, envelope_1.toProtoPayload)(input)),
86
+ });
87
+ return this.sendAndTrack(envelope, input.auth);
88
+ }
89
+ async rejectTask(input) {
90
+ (0, validation_1.validateRequiredField)('taskId', input.taskId);
91
+ const envelope = (0, envelope_1.buildEnvelope)({
92
+ mode: constants_1.MODE_TASK,
93
+ messageType: 'TaskReject',
94
+ sessionId: this.sessionId,
95
+ sender: this.senderFor(input.sender, input.auth),
96
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'TaskReject', (0, envelope_1.toProtoPayload)(input)),
97
+ });
98
+ return this.sendAndTrack(envelope, input.auth);
99
+ }
100
+ async update(input) {
101
+ (0, validation_1.validateRequiredField)('taskId', input.taskId);
102
+ const envelope = (0, envelope_1.buildEnvelope)({
103
+ mode: constants_1.MODE_TASK,
104
+ messageType: 'TaskUpdate',
105
+ sessionId: this.sessionId,
106
+ sender: this.senderFor(input.sender, input.auth),
107
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'TaskUpdate', (0, envelope_1.toProtoPayload)(input)),
108
+ });
109
+ return this.sendAndTrack(envelope, input.auth);
110
+ }
111
+ async complete(input) {
112
+ (0, validation_1.validateRequiredField)('taskId', input.taskId);
113
+ const envelope = (0, envelope_1.buildEnvelope)({
114
+ mode: constants_1.MODE_TASK,
115
+ messageType: 'TaskComplete',
116
+ sessionId: this.sessionId,
117
+ sender: this.senderFor(input.sender, input.auth),
118
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'TaskComplete', (0, envelope_1.toProtoPayload)(input)),
119
+ });
120
+ return this.sendAndTrack(envelope, input.auth);
121
+ }
122
+ async fail(input) {
123
+ (0, validation_1.validateRequiredField)('taskId', input.taskId);
124
+ const envelope = (0, envelope_1.buildEnvelope)({
125
+ mode: constants_1.MODE_TASK,
126
+ messageType: 'TaskFail',
127
+ sessionId: this.sessionId,
128
+ sender: this.senderFor(input.sender, input.auth),
129
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'TaskFail', (0, envelope_1.toProtoPayload)(input)),
130
+ });
131
+ return this.sendAndTrack(envelope, input.auth);
132
+ }
133
+ async commit(input) {
134
+ const payload = (0, envelope_1.buildCommitmentPayload)({
135
+ action: input.action,
136
+ authorityScope: input.authorityScope,
137
+ reason: input.reason,
138
+ commitmentId: input.commitmentId,
139
+ outcomePositive: input.outcomePositive,
140
+ modeVersion: this.modeVersion,
141
+ configurationVersion: this.configurationVersion,
142
+ policyVersion: this.policyVersion,
143
+ });
144
+ const envelope = (0, envelope_1.buildEnvelope)({
145
+ mode: constants_1.MODE_TASK,
146
+ messageType: 'Commitment',
147
+ sessionId: this.sessionId,
148
+ sender: this.senderFor(input.sender, input.auth),
149
+ payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_TASK, 'Commitment', (0, envelope_1.toProtoPayload)(payload)),
150
+ });
151
+ return this.sendAndTrack(envelope, input.auth);
152
+ }
153
+ metadata(auth) {
154
+ return this.client.getSession(this.sessionId, { auth: auth ?? this.auth });
155
+ }
156
+ async cancel(reason = '', auth) {
157
+ return this.client.cancelSession(this.sessionId, reason, {
158
+ auth: auth ?? this.auth,
159
+ raiseOnNack: true,
160
+ });
161
+ }
162
+ openStream(auth) {
163
+ return this.client.openStream({ auth: auth ?? this.auth });
164
+ }
165
+ }
166
+ exports.TaskSession = TaskSession;