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.
- package/CHANGELOG.md +73 -0
- package/LICENSE +201 -0
- package/README.md +307 -0
- package/dist/agent/dispatcher.d.ts +16 -0
- package/dist/agent/dispatcher.js +61 -0
- package/dist/agent/index.d.ts +6 -0
- package/dist/agent/index.js +25 -0
- package/dist/agent/participant.d.ts +38 -0
- package/dist/agent/participant.js +221 -0
- package/dist/agent/runner.d.ts +18 -0
- package/dist/agent/runner.js +84 -0
- package/dist/agent/strategies.d.ts +40 -0
- package/dist/agent/strategies.js +106 -0
- package/dist/agent/transports.d.ts +35 -0
- package/dist/agent/transports.js +125 -0
- package/dist/agent/types.d.ts +72 -0
- package/dist/agent/types.js +2 -0
- package/dist/auth.d.ts +52 -0
- package/dist/auth.js +112 -0
- package/dist/client.d.ts +171 -0
- package/dist/client.js +384 -0
- package/dist/constants.d.ts +26 -0
- package/dist/constants.js +29 -0
- package/dist/decision.d.ts +65 -0
- package/dist/decision.js +148 -0
- package/dist/envelope.d.ts +50 -0
- package/dist/envelope.js +97 -0
- package/dist/errors.d.ts +44 -0
- package/dist/errors.js +114 -0
- package/dist/handoff.d.ts +73 -0
- package/dist/handoff.js +160 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +57 -0
- package/dist/policy.d.ts +76 -0
- package/dist/policy.js +118 -0
- package/dist/projections/decision.d.ts +49 -0
- package/dist/projections/decision.js +132 -0
- package/dist/projections/handoff.d.ts +28 -0
- package/dist/projections/handoff.js +111 -0
- package/dist/projections/proposal.d.ts +40 -0
- package/dist/projections/proposal.js +123 -0
- package/dist/projections/quorum.d.ts +36 -0
- package/dist/projections/quorum.js +107 -0
- package/dist/projections/task.d.ts +54 -0
- package/dist/projections/task.js +127 -0
- package/dist/projections.d.ts +5 -0
- package/dist/projections.js +21 -0
- package/dist/proposal.d.ts +69 -0
- package/dist/proposal.js +155 -0
- package/dist/proto-registry.d.ts +12 -0
- package/dist/proto-registry.js +165 -0
- package/dist/quorum.d.ts +65 -0
- package/dist/quorum.js +144 -0
- package/dist/retry.d.ts +14 -0
- package/dist/retry.js +48 -0
- package/dist/task.d.ts +73 -0
- package/dist/task.js +166 -0
- package/dist/types.d.ts +263 -0
- package/dist/types.js +2 -0
- package/dist/validation.d.ts +17 -0
- package/dist/validation.js +92 -0
- package/dist/watchers.d.ts +47 -0
- package/dist/watchers.js +176 -0
- package/package.json +72 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Envelope } from '../types';
|
|
2
|
+
import type { ProtoRegistry } from '../proto-registry';
|
|
3
|
+
export interface ApprovalRequestRecord {
|
|
4
|
+
requestId: string;
|
|
5
|
+
action: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
requiredApprovals: number;
|
|
8
|
+
sender: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BallotRecord {
|
|
11
|
+
requestId: string;
|
|
12
|
+
vote: 'approve' | 'reject' | 'abstain';
|
|
13
|
+
reason?: string;
|
|
14
|
+
sender: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class QuorumProjection {
|
|
17
|
+
readonly requests: Map<string, ApprovalRequestRecord>;
|
|
18
|
+
readonly ballots: Map<string, Map<string, BallotRecord>>;
|
|
19
|
+
readonly transcript: Envelope[];
|
|
20
|
+
phase: 'Pending' | 'Voting' | 'Committed';
|
|
21
|
+
commitment?: Record<string, unknown>;
|
|
22
|
+
applyEnvelope(envelope: Envelope, protoRegistry: ProtoRegistry): void;
|
|
23
|
+
get isCommitted(): boolean;
|
|
24
|
+
get isPositiveOutcome(): boolean | undefined;
|
|
25
|
+
private setBallot;
|
|
26
|
+
approvalCount(requestId: string): number;
|
|
27
|
+
rejectionCount(requestId: string): number;
|
|
28
|
+
abstentionCount(requestId: string): number;
|
|
29
|
+
hasQuorum(requestId: string): boolean;
|
|
30
|
+
threshold(requestId: string): number;
|
|
31
|
+
votedSenders(requestId: string): string[];
|
|
32
|
+
remainingVotesNeeded(requestId: string): number;
|
|
33
|
+
commitmentReady(requestId: string): boolean;
|
|
34
|
+
isThresholdUnreachable(requestId: string, totalEligible: number): boolean;
|
|
35
|
+
private countVotes;
|
|
36
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QuorumProjection = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
class QuorumProjection {
|
|
6
|
+
requests = new Map();
|
|
7
|
+
ballots = new Map();
|
|
8
|
+
transcript = [];
|
|
9
|
+
phase = 'Pending';
|
|
10
|
+
commitment;
|
|
11
|
+
applyEnvelope(envelope, protoRegistry) {
|
|
12
|
+
if (envelope.mode !== constants_1.MODE_QUORUM)
|
|
13
|
+
return;
|
|
14
|
+
this.transcript.push(envelope);
|
|
15
|
+
const payload = protoRegistry.decodeKnownPayload(envelope.mode, envelope.messageType, envelope.payload);
|
|
16
|
+
switch (envelope.messageType) {
|
|
17
|
+
case 'ApprovalRequest': {
|
|
18
|
+
const record = payload;
|
|
19
|
+
this.requests.set(record.requestId, { ...record, sender: envelope.sender });
|
|
20
|
+
this.phase = 'Voting';
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
case 'Approve': {
|
|
24
|
+
const record = payload;
|
|
25
|
+
this.setBallot(record.requestId, envelope.sender, 'approve', record.reason);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case 'Reject': {
|
|
29
|
+
const record = payload;
|
|
30
|
+
this.setBallot(record.requestId, envelope.sender, 'reject', record.reason);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
case 'Abstain': {
|
|
34
|
+
const record = payload;
|
|
35
|
+
this.setBallot(record.requestId, envelope.sender, 'abstain', record.reason);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case 'Commitment': {
|
|
39
|
+
this.commitment = payload;
|
|
40
|
+
this.phase = 'Committed';
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
default:
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
get isCommitted() {
|
|
48
|
+
return this.commitment !== undefined;
|
|
49
|
+
}
|
|
50
|
+
get isPositiveOutcome() {
|
|
51
|
+
if (!this.commitment)
|
|
52
|
+
return undefined;
|
|
53
|
+
const val = this.commitment.outcomePositive ??
|
|
54
|
+
this.commitment.outcome_positive;
|
|
55
|
+
return val !== undefined ? Boolean(val) : true;
|
|
56
|
+
}
|
|
57
|
+
setBallot(requestId, sender, vote, reason) {
|
|
58
|
+
const senderMap = this.ballots.get(requestId) ?? new Map();
|
|
59
|
+
senderMap.set(sender, { requestId, vote, reason, sender });
|
|
60
|
+
this.ballots.set(requestId, senderMap);
|
|
61
|
+
}
|
|
62
|
+
approvalCount(requestId) {
|
|
63
|
+
return this.countVotes(requestId, 'approve');
|
|
64
|
+
}
|
|
65
|
+
rejectionCount(requestId) {
|
|
66
|
+
return this.countVotes(requestId, 'reject');
|
|
67
|
+
}
|
|
68
|
+
abstentionCount(requestId) {
|
|
69
|
+
return this.countVotes(requestId, 'abstain');
|
|
70
|
+
}
|
|
71
|
+
hasQuorum(requestId) {
|
|
72
|
+
const req = this.requests.get(requestId);
|
|
73
|
+
if (!req)
|
|
74
|
+
return false;
|
|
75
|
+
return this.approvalCount(requestId) >= req.requiredApprovals;
|
|
76
|
+
}
|
|
77
|
+
threshold(requestId) {
|
|
78
|
+
return this.requests.get(requestId)?.requiredApprovals ?? 0;
|
|
79
|
+
}
|
|
80
|
+
votedSenders(requestId) {
|
|
81
|
+
const senderMap = this.ballots.get(requestId);
|
|
82
|
+
return senderMap ? [...senderMap.keys()] : [];
|
|
83
|
+
}
|
|
84
|
+
remainingVotesNeeded(requestId) {
|
|
85
|
+
const req = this.requests.get(requestId);
|
|
86
|
+
if (!req)
|
|
87
|
+
return 0;
|
|
88
|
+
return Math.max(0, req.requiredApprovals - this.approvalCount(requestId));
|
|
89
|
+
}
|
|
90
|
+
commitmentReady(requestId) {
|
|
91
|
+
return this.hasQuorum(requestId) && this.phase !== 'Committed';
|
|
92
|
+
}
|
|
93
|
+
isThresholdUnreachable(requestId, totalEligible) {
|
|
94
|
+
const req = this.requests.get(requestId);
|
|
95
|
+
if (!req)
|
|
96
|
+
return false;
|
|
97
|
+
const remaining = totalEligible - this.votedSenders(requestId).length;
|
|
98
|
+
return this.approvalCount(requestId) + remaining < req.requiredApprovals;
|
|
99
|
+
}
|
|
100
|
+
countVotes(requestId, vote) {
|
|
101
|
+
const senderMap = this.ballots.get(requestId);
|
|
102
|
+
if (!senderMap)
|
|
103
|
+
return 0;
|
|
104
|
+
return [...senderMap.values()].filter((b) => b.vote === vote).length;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.QuorumProjection = QuorumProjection;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Envelope } from '../types';
|
|
2
|
+
import type { ProtoRegistry } from '../proto-registry';
|
|
3
|
+
export interface TaskRecord {
|
|
4
|
+
taskId: string;
|
|
5
|
+
title: string;
|
|
6
|
+
instructions: string;
|
|
7
|
+
requestedAssignee?: string;
|
|
8
|
+
assignee?: string;
|
|
9
|
+
deadlineUnixMs?: number;
|
|
10
|
+
status: 'requested' | 'accepted' | 'rejected' | 'in_progress' | 'completed' | 'failed';
|
|
11
|
+
progress: number;
|
|
12
|
+
sender: string;
|
|
13
|
+
}
|
|
14
|
+
export interface TaskUpdateRecord {
|
|
15
|
+
taskId: string;
|
|
16
|
+
status: string;
|
|
17
|
+
progress: number;
|
|
18
|
+
message?: string;
|
|
19
|
+
sender: string;
|
|
20
|
+
}
|
|
21
|
+
export interface TaskCompletionRecord {
|
|
22
|
+
taskId: string;
|
|
23
|
+
assignee: string;
|
|
24
|
+
summary?: string;
|
|
25
|
+
sender: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TaskFailureRecord {
|
|
28
|
+
taskId: string;
|
|
29
|
+
assignee: string;
|
|
30
|
+
errorCode?: string;
|
|
31
|
+
reason?: string;
|
|
32
|
+
retryable: boolean;
|
|
33
|
+
sender: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class TaskProjection {
|
|
36
|
+
readonly tasks: Map<string, TaskRecord>;
|
|
37
|
+
readonly updates: TaskUpdateRecord[];
|
|
38
|
+
readonly completions: TaskCompletionRecord[];
|
|
39
|
+
readonly failures: TaskFailureRecord[];
|
|
40
|
+
readonly transcript: Envelope[];
|
|
41
|
+
phase: 'Pending' | 'Requested' | 'InProgress' | 'Completed' | 'Failed' | 'Committed';
|
|
42
|
+
commitment?: Record<string, unknown>;
|
|
43
|
+
applyEnvelope(envelope: Envelope, protoRegistry: ProtoRegistry): void;
|
|
44
|
+
get isCommitted(): boolean;
|
|
45
|
+
get isPositiveOutcome(): boolean | undefined;
|
|
46
|
+
getTask(taskId: string): TaskRecord | undefined;
|
|
47
|
+
isComplete(taskId: string): boolean;
|
|
48
|
+
isFailed(taskId: string): boolean;
|
|
49
|
+
isRetryable(taskId: string): boolean;
|
|
50
|
+
progressOf(taskId: string): number;
|
|
51
|
+
activeTasks(): TaskRecord[];
|
|
52
|
+
isAccepted(taskId: string): boolean;
|
|
53
|
+
latestProgress(): number | undefined;
|
|
54
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaskProjection = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
class TaskProjection {
|
|
6
|
+
tasks = new Map();
|
|
7
|
+
updates = [];
|
|
8
|
+
completions = [];
|
|
9
|
+
failures = [];
|
|
10
|
+
transcript = [];
|
|
11
|
+
phase = 'Pending';
|
|
12
|
+
commitment;
|
|
13
|
+
applyEnvelope(envelope, protoRegistry) {
|
|
14
|
+
if (envelope.mode !== constants_1.MODE_TASK)
|
|
15
|
+
return;
|
|
16
|
+
this.transcript.push(envelope);
|
|
17
|
+
const payload = protoRegistry.decodeKnownPayload(envelope.mode, envelope.messageType, envelope.payload);
|
|
18
|
+
switch (envelope.messageType) {
|
|
19
|
+
case 'TaskRequest': {
|
|
20
|
+
const record = payload;
|
|
21
|
+
this.tasks.set(record.taskId, {
|
|
22
|
+
taskId: record.taskId,
|
|
23
|
+
title: record.title,
|
|
24
|
+
instructions: record.instructions,
|
|
25
|
+
requestedAssignee: record.requestedAssignee,
|
|
26
|
+
deadlineUnixMs: record.deadlineUnixMs,
|
|
27
|
+
status: 'requested',
|
|
28
|
+
progress: 0,
|
|
29
|
+
sender: envelope.sender,
|
|
30
|
+
});
|
|
31
|
+
this.phase = 'Requested';
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 'TaskAccept': {
|
|
35
|
+
const record = payload;
|
|
36
|
+
const task = this.tasks.get(record.taskId);
|
|
37
|
+
if (task) {
|
|
38
|
+
task.assignee = record.assignee;
|
|
39
|
+
task.status = 'accepted';
|
|
40
|
+
}
|
|
41
|
+
this.phase = 'InProgress';
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case 'TaskReject': {
|
|
45
|
+
const record = payload;
|
|
46
|
+
const task = this.tasks.get(record.taskId);
|
|
47
|
+
if (task)
|
|
48
|
+
task.status = 'rejected';
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case 'TaskUpdate': {
|
|
52
|
+
const record = payload;
|
|
53
|
+
this.updates.push({ ...record, sender: envelope.sender });
|
|
54
|
+
const task = this.tasks.get(record.taskId);
|
|
55
|
+
if (task) {
|
|
56
|
+
task.progress = record.progress;
|
|
57
|
+
task.status = 'in_progress';
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'TaskComplete': {
|
|
62
|
+
const record = payload;
|
|
63
|
+
this.completions.push({ ...record, sender: envelope.sender });
|
|
64
|
+
const task = this.tasks.get(record.taskId);
|
|
65
|
+
if (task) {
|
|
66
|
+
task.status = 'completed';
|
|
67
|
+
task.progress = 1;
|
|
68
|
+
}
|
|
69
|
+
this.phase = 'Completed';
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case 'TaskFail': {
|
|
73
|
+
const record = payload;
|
|
74
|
+
this.failures.push({ ...record, retryable: record.retryable ?? false, sender: envelope.sender });
|
|
75
|
+
const task = this.tasks.get(record.taskId);
|
|
76
|
+
if (task)
|
|
77
|
+
task.status = 'failed';
|
|
78
|
+
this.phase = 'Failed';
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case 'Commitment': {
|
|
82
|
+
this.commitment = payload;
|
|
83
|
+
this.phase = 'Committed';
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
default:
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
get isCommitted() {
|
|
91
|
+
return this.commitment !== undefined;
|
|
92
|
+
}
|
|
93
|
+
get isPositiveOutcome() {
|
|
94
|
+
if (!this.commitment)
|
|
95
|
+
return undefined;
|
|
96
|
+
const val = this.commitment.outcomePositive ??
|
|
97
|
+
this.commitment.outcome_positive;
|
|
98
|
+
return val !== undefined ? Boolean(val) : true;
|
|
99
|
+
}
|
|
100
|
+
getTask(taskId) {
|
|
101
|
+
return this.tasks.get(taskId);
|
|
102
|
+
}
|
|
103
|
+
isComplete(taskId) {
|
|
104
|
+
return this.tasks.get(taskId)?.status === 'completed';
|
|
105
|
+
}
|
|
106
|
+
isFailed(taskId) {
|
|
107
|
+
return this.tasks.get(taskId)?.status === 'failed';
|
|
108
|
+
}
|
|
109
|
+
isRetryable(taskId) {
|
|
110
|
+
return this.failures.some((f) => f.taskId === taskId && f.retryable);
|
|
111
|
+
}
|
|
112
|
+
progressOf(taskId) {
|
|
113
|
+
return this.tasks.get(taskId)?.progress ?? 0;
|
|
114
|
+
}
|
|
115
|
+
activeTasks() {
|
|
116
|
+
const active = new Set(['requested', 'accepted', 'in_progress']);
|
|
117
|
+
return [...this.tasks.values()].filter((t) => active.has(t.status));
|
|
118
|
+
}
|
|
119
|
+
isAccepted(taskId) {
|
|
120
|
+
const status = this.tasks.get(taskId)?.status;
|
|
121
|
+
return status === 'accepted' || status === 'in_progress';
|
|
122
|
+
}
|
|
123
|
+
latestProgress() {
|
|
124
|
+
return this.updates[this.updates.length - 1]?.progress;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.TaskProjection = TaskProjection;
|
|
@@ -0,0 +1,21 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./projections/decision"), exports);
|
|
18
|
+
__exportStar(require("./projections/proposal"), exports);
|
|
19
|
+
__exportStar(require("./projections/task"), exports);
|
|
20
|
+
__exportStar(require("./projections/handoff"), exports);
|
|
21
|
+
__exportStar(require("./projections/quorum"), exports);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type AuthConfig } from './auth';
|
|
2
|
+
import type { MacpClient, MacpStream } from './client';
|
|
3
|
+
import { ProposalProjection } from './projections/proposal';
|
|
4
|
+
import type { AcceptPayload, Ack, CounterProposalPayload, ProposalModeProposalPayload, RejectPayload, SessionMetadata, WithdrawPayload } from './types';
|
|
5
|
+
interface ProposalSessionOptions {
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
modeVersion?: string;
|
|
8
|
+
configurationVersion?: string;
|
|
9
|
+
policyVersion?: string;
|
|
10
|
+
auth?: AuthConfig;
|
|
11
|
+
}
|
|
12
|
+
export declare class ProposalSession {
|
|
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: ProposalProjection;
|
|
20
|
+
constructor(client: MacpClient, options?: ProposalSessionOptions);
|
|
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: ProposalModeProposalPayload & {
|
|
35
|
+
sender?: string;
|
|
36
|
+
auth?: AuthConfig;
|
|
37
|
+
}): Promise<Ack>;
|
|
38
|
+
counterPropose(input: CounterProposalPayload & {
|
|
39
|
+
sender?: string;
|
|
40
|
+
auth?: AuthConfig;
|
|
41
|
+
}): Promise<Ack>;
|
|
42
|
+
accept(input: AcceptPayload & {
|
|
43
|
+
sender?: string;
|
|
44
|
+
auth?: AuthConfig;
|
|
45
|
+
}): Promise<Ack>;
|
|
46
|
+
reject(input: RejectPayload & {
|
|
47
|
+
sender?: string;
|
|
48
|
+
auth?: AuthConfig;
|
|
49
|
+
}): Promise<Ack>;
|
|
50
|
+
withdraw(input: WithdrawPayload & {
|
|
51
|
+
sender?: string;
|
|
52
|
+
auth?: AuthConfig;
|
|
53
|
+
}): Promise<Ack>;
|
|
54
|
+
commit(input: {
|
|
55
|
+
action: string;
|
|
56
|
+
authorityScope: string;
|
|
57
|
+
reason: string;
|
|
58
|
+
commitmentId?: string;
|
|
59
|
+
outcomePositive?: boolean;
|
|
60
|
+
sender?: string;
|
|
61
|
+
auth?: AuthConfig;
|
|
62
|
+
}): Promise<Ack>;
|
|
63
|
+
metadata(auth?: AuthConfig): Promise<{
|
|
64
|
+
metadata: SessionMetadata;
|
|
65
|
+
}>;
|
|
66
|
+
cancel(reason?: string, auth?: AuthConfig): Promise<Ack>;
|
|
67
|
+
openStream(auth?: AuthConfig): MacpStream;
|
|
68
|
+
}
|
|
69
|
+
export {};
|
package/dist/proposal.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProposalSession = void 0;
|
|
4
|
+
const auth_1 = require("./auth");
|
|
5
|
+
const constants_1 = require("./constants");
|
|
6
|
+
const envelope_1 = require("./envelope");
|
|
7
|
+
const proposal_1 = require("./projections/proposal");
|
|
8
|
+
const validation_1 = require("./validation");
|
|
9
|
+
class ProposalSession {
|
|
10
|
+
client;
|
|
11
|
+
sessionId;
|
|
12
|
+
modeVersion;
|
|
13
|
+
configurationVersion;
|
|
14
|
+
policyVersion;
|
|
15
|
+
auth;
|
|
16
|
+
projection = new proposal_1.ProposalProjection();
|
|
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_PROPOSAL,
|
|
58
|
+
messageType: 'SessionStart',
|
|
59
|
+
sessionId: this.sessionId,
|
|
60
|
+
sender: this.senderFor(input.sender),
|
|
61
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, '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)('title', input.title);
|
|
68
|
+
const envelope = (0, envelope_1.buildEnvelope)({
|
|
69
|
+
mode: constants_1.MODE_PROPOSAL,
|
|
70
|
+
messageType: 'Proposal',
|
|
71
|
+
sessionId: this.sessionId,
|
|
72
|
+
sender: this.senderFor(input.sender, input.auth),
|
|
73
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, 'Proposal', (0, envelope_1.toProtoPayload)(input)),
|
|
74
|
+
});
|
|
75
|
+
return this.sendAndTrack(envelope, input.auth);
|
|
76
|
+
}
|
|
77
|
+
async counterPropose(input) {
|
|
78
|
+
(0, validation_1.validateRequiredField)('proposalId', input.proposalId);
|
|
79
|
+
(0, validation_1.validateRequiredField)('title', input.title);
|
|
80
|
+
const envelope = (0, envelope_1.buildEnvelope)({
|
|
81
|
+
mode: constants_1.MODE_PROPOSAL,
|
|
82
|
+
messageType: 'CounterProposal',
|
|
83
|
+
sessionId: this.sessionId,
|
|
84
|
+
sender: this.senderFor(input.sender, input.auth),
|
|
85
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, 'CounterProposal', (0, envelope_1.toProtoPayload)(input)),
|
|
86
|
+
});
|
|
87
|
+
return this.sendAndTrack(envelope, input.auth);
|
|
88
|
+
}
|
|
89
|
+
async accept(input) {
|
|
90
|
+
(0, validation_1.validateRequiredField)('proposalId', input.proposalId);
|
|
91
|
+
const envelope = (0, envelope_1.buildEnvelope)({
|
|
92
|
+
mode: constants_1.MODE_PROPOSAL,
|
|
93
|
+
messageType: 'Accept',
|
|
94
|
+
sessionId: this.sessionId,
|
|
95
|
+
sender: this.senderFor(input.sender, input.auth),
|
|
96
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, 'Accept', (0, envelope_1.toProtoPayload)(input)),
|
|
97
|
+
});
|
|
98
|
+
return this.sendAndTrack(envelope, input.auth);
|
|
99
|
+
}
|
|
100
|
+
async reject(input) {
|
|
101
|
+
(0, validation_1.validateRequiredField)('proposalId', input.proposalId);
|
|
102
|
+
const envelope = (0, envelope_1.buildEnvelope)({
|
|
103
|
+
mode: constants_1.MODE_PROPOSAL,
|
|
104
|
+
messageType: 'Reject',
|
|
105
|
+
sessionId: this.sessionId,
|
|
106
|
+
sender: this.senderFor(input.sender, input.auth),
|
|
107
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, 'Reject', (0, envelope_1.toProtoPayload)(input)),
|
|
108
|
+
});
|
|
109
|
+
return this.sendAndTrack(envelope, input.auth);
|
|
110
|
+
}
|
|
111
|
+
async withdraw(input) {
|
|
112
|
+
(0, validation_1.validateRequiredField)('proposalId', input.proposalId);
|
|
113
|
+
const envelope = (0, envelope_1.buildEnvelope)({
|
|
114
|
+
mode: constants_1.MODE_PROPOSAL,
|
|
115
|
+
messageType: 'Withdraw',
|
|
116
|
+
sessionId: this.sessionId,
|
|
117
|
+
sender: this.senderFor(input.sender, input.auth),
|
|
118
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, 'Withdraw', (0, envelope_1.toProtoPayload)(input)),
|
|
119
|
+
});
|
|
120
|
+
return this.sendAndTrack(envelope, input.auth);
|
|
121
|
+
}
|
|
122
|
+
async commit(input) {
|
|
123
|
+
const payload = (0, envelope_1.buildCommitmentPayload)({
|
|
124
|
+
action: input.action,
|
|
125
|
+
authorityScope: input.authorityScope,
|
|
126
|
+
reason: input.reason,
|
|
127
|
+
commitmentId: input.commitmentId,
|
|
128
|
+
outcomePositive: input.outcomePositive,
|
|
129
|
+
modeVersion: this.modeVersion,
|
|
130
|
+
configurationVersion: this.configurationVersion,
|
|
131
|
+
policyVersion: this.policyVersion,
|
|
132
|
+
});
|
|
133
|
+
const envelope = (0, envelope_1.buildEnvelope)({
|
|
134
|
+
mode: constants_1.MODE_PROPOSAL,
|
|
135
|
+
messageType: 'Commitment',
|
|
136
|
+
sessionId: this.sessionId,
|
|
137
|
+
sender: this.senderFor(input.sender, input.auth),
|
|
138
|
+
payload: this.client.protoRegistry.encodeKnownPayload(constants_1.MODE_PROPOSAL, 'Commitment', (0, envelope_1.toProtoPayload)(payload)),
|
|
139
|
+
});
|
|
140
|
+
return this.sendAndTrack(envelope, input.auth);
|
|
141
|
+
}
|
|
142
|
+
metadata(auth) {
|
|
143
|
+
return this.client.getSession(this.sessionId, { auth: auth ?? this.auth });
|
|
144
|
+
}
|
|
145
|
+
async cancel(reason = '', auth) {
|
|
146
|
+
return this.client.cancelSession(this.sessionId, reason, {
|
|
147
|
+
auth: auth ?? this.auth,
|
|
148
|
+
raiseOnNack: true,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
openStream(auth) {
|
|
152
|
+
return this.client.openStream({ auth: auth ?? this.auth });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.ProposalSession = ProposalSession;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class ProtoRegistry {
|
|
2
|
+
readonly protoDir: string;
|
|
3
|
+
private root;
|
|
4
|
+
constructor(protoDir?: string);
|
|
5
|
+
getKnownTypeName(mode: string, messageType: string): string | undefined;
|
|
6
|
+
encodeMessage(typeName: string, value: Record<string, unknown>): Buffer;
|
|
7
|
+
decodeMessage(typeName: string, payload: Buffer): Record<string, unknown>;
|
|
8
|
+
encodeKnownPayload(mode: string, messageType: string, value: Record<string, unknown>): Buffer;
|
|
9
|
+
decodeKnownPayload(mode: string, messageType: string, payload: Buffer): Record<string, unknown> | undefined;
|
|
10
|
+
private lookupType;
|
|
11
|
+
private tryDecodeUtf8;
|
|
12
|
+
}
|