macp-sdk-typescript 0.14.0 → 0.14.1
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 +69 -0
- package/dist/policy.js +7 -3
- package/dist/projections/base.d.ts +14 -0
- package/dist/projections/base.js +18 -0
- package/dist/projections/decision.js +22 -15
- package/dist/projections/handoff.js +4 -4
- package/dist/projections/proposal.d.ts +13 -0
- package/dist/projections/proposal.js +19 -2
- package/dist/projections/quorum.js +1 -1
- package/dist/projections/task.d.ts +7 -0
- package/dist/projections/task.js +15 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watchers.js +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,75 @@ All notable changes to `macp-sdk-typescript` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
|
|
5
5
|
project uses [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.14.1](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.14.0...v0.14.1) (2026-10-03)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **parity:** re-vendor contract.json for contract_version 1.3.0 ([#156](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/156)) ([#157](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/157)) ([497949d](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/497949d2b29031d340f5d8cc2ef17ae34c946c42))
|
|
13
|
+
|
|
14
|
+
## [Unreleased]
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`TaskProjection.rejections: TaskRejectRecord[]`** (issue #151; a
|
|
19
|
+
cross-SDK parity audit against `macp-sdk-python`'s `TaskRejectRecord`,
|
|
20
|
+
`src/macp_sdk/task.py:53-58`). `TaskReject` now appends an unconditional
|
|
21
|
+
audit record — `taskId`, `assignee`, `reason?`, `sender` (from the
|
|
22
|
+
envelope, not the payload) — matching the convention already established
|
|
23
|
+
for `updates`/`completions`/`failures`. A `TaskReject` for an unknown
|
|
24
|
+
`taskId` still records a `rejections` entry (no crash, no silent drop) but
|
|
25
|
+
creates no `tasks` entry, unchanged from today. Deliberately does not fall
|
|
26
|
+
back `assignee` to the envelope sender the way Python's `p.assignee or
|
|
27
|
+
envelope.sender` does — this SDK's own sibling `TaskComplete`/`TaskFail`
|
|
28
|
+
handlers spread the payload's `assignee` as-is with no such fallback, and
|
|
29
|
+
intra-SDK consistency with that established pattern takes precedence here.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- **`BaseProjection` phase no longer regresses once `Committed`, and
|
|
34
|
+
`DecisionProjection` no longer lets a replayed `Proposal` rewind phase
|
|
35
|
+
from `Voting` back to `Evaluation` after voting has begun** (issue #150,
|
|
36
|
+
issue #153; found by a cross-SDK parity audit against `macp-sdk-python`'s
|
|
37
|
+
`_set_phase()`, `src/macp_sdk/base_projection.py:289-313`). All five
|
|
38
|
+
built-in mode projections now route every phase write through a new
|
|
39
|
+
shared, protected `setPhase()` choke point on `BaseProjection` that
|
|
40
|
+
no-ops once `phase === 'Committed'`, instead of assigning `this.phase`
|
|
41
|
+
directly at each of the (previously) 12 call sites across
|
|
42
|
+
`decision.ts`/`proposal.ts`/`task.ts`/`quorum.ts`/`handoff.ts` — only
|
|
43
|
+
`decision.ts`'s own Vote-branch guard protected this before. RFC-MACP-0007
|
|
44
|
+
§5 rule 6 separately requires a runtime to reject any
|
|
45
|
+
`Proposal`/`Evaluation`/`Objection` after the first accepted `Vote`;
|
|
46
|
+
`DecisionProjection`'s `Proposal` handler now guards on the pre-
|
|
47
|
+
`Evaluation` phase value (`if (this.phase === 'Proposal')
|
|
48
|
+
this.setPhase('Evaluation')`) so a replayed/retried `Proposal` (same
|
|
49
|
+
`proposalId`, a distinct `messageId` that still passes
|
|
50
|
+
`applyEnvelope`'s `message_id` dedup gate) can no longer rewind `phase`
|
|
51
|
+
back to `'Evaluation'` once voting has begun. `BaseProjection.
|
|
52
|
+
applyEnvelope`'s own direct `this.phase = 'Committed'` assignment for a
|
|
53
|
+
`Commitment` envelope is deliberately left untouched — exact parity with
|
|
54
|
+
Python's own `_set_phase()` docstring, which documents the same bypass.
|
|
55
|
+
- **`buildDecisionPolicy` now rejects a `+Infinity` voting weight** (issue
|
|
56
|
+
#152; found by a cross-SDK parity audit against `macp-sdk-python`'s
|
|
57
|
+
`math.isfinite` guard, `src/macp_sdk/policy.py:186`). The per-weight
|
|
58
|
+
validation guard changed from `weight <= 0 || Number.isNaN(weight)` to
|
|
59
|
+
`weight <= 0 || !Number.isFinite(weight)` — `!Number.isFinite` is `true`
|
|
60
|
+
for `NaN`, `+Infinity`, and `-Infinity` alike, closing the `+Infinity` gap
|
|
61
|
+
the old `Number.isNaN`-only check missed (a `+Infinity` weight serializes
|
|
62
|
+
to JSON `null`, which is schema-invalid against
|
|
63
|
+
`decision-rules.schema.json`). `-Infinity`/`NaN` continue to throw,
|
|
64
|
+
unchanged.
|
|
65
|
+
- **`watchers.ts`'s 5 "stream ended before receiving a ..." sites now throw
|
|
66
|
+
`MacpTransportError` instead of a bare `Error`** (issue #154; parity with
|
|
67
|
+
`macp-sdk-python` PR #138). `ModeRegistryWatcher.nextChange()`,
|
|
68
|
+
`RootsWatcher.nextChange()`, `SignalWatcher.nextSignal()`,
|
|
69
|
+
`PolicyWatcher.nextChange()`, and `SessionLifecycleWatcher.nextChange()`
|
|
70
|
+
each threw a bare `Error` when their stream ended before yielding a value;
|
|
71
|
+
a caller's single `catch (e) { if (e instanceof MacpSdkError) ... }` now
|
|
72
|
+
covers a cleanly-ended watch stream alongside every other SDK failure.
|
|
73
|
+
Message strings are unchanged byte-for-byte; `error.code` remains
|
|
74
|
+
`undefined` on all 5 (locally raised, no gRPC status to attach).
|
|
75
|
+
|
|
7
76
|
## [0.14.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.13.0...v0.14.0) (2026-10-01)
|
|
8
77
|
|
|
9
78
|
|
package/dist/policy.js
CHANGED
|
@@ -105,9 +105,13 @@ function buildDecisionPolicy(policyId, description, rules, options) {
|
|
|
105
105
|
}
|
|
106
106
|
for (const [participant, weight] of Object.entries(weights)) {
|
|
107
107
|
// weight <= 0 alone would let a NaN weight slip through (NaN <= 0 is
|
|
108
|
-
// false); the runtime guards this explicitly (registry.rs:596)
|
|
109
|
-
//
|
|
110
|
-
|
|
108
|
+
// false); the runtime guards this explicitly (registry.rs:596).
|
|
109
|
+
// !Number.isFinite(weight) is true for NaN, +Infinity, and -Infinity
|
|
110
|
+
// alike -- the exact mirror of Python's own guard, policy.py:186:
|
|
111
|
+
// `if not math.isfinite(weight) or weight <= 0:` (issue #152; a
|
|
112
|
+
// +Infinity weight previously slipped past the old Number.isNaN-only
|
|
113
|
+
// check and serialized to JSON `null`, which is schema-invalid).
|
|
114
|
+
if (weight <= 0 || !Number.isFinite(weight)) {
|
|
111
115
|
throw new errors_1.MacpSessionError(`weights['${participant}'] must be > 0, got ${weight} -- a weight-0 observer is expressed by ` +
|
|
112
116
|
'omission from the map, not by an explicit 0');
|
|
113
117
|
}
|
|
@@ -226,4 +226,18 @@ export declare abstract class BaseProjection {
|
|
|
226
226
|
* `MACP_LOG_LEVEL` environment variable.
|
|
227
227
|
*/
|
|
228
228
|
protected recordAnomaly(anomaly: ProjectionAnomaly): void;
|
|
229
|
+
/**
|
|
230
|
+
* Assign `this.phase`, guarding against regression out of the terminal
|
|
231
|
+
* `'Committed'` state — parity with macp-sdk-python's `_set_phase`
|
|
232
|
+
* (`base_projection.py:289-313`). `applyEnvelope` sets `this.phase =
|
|
233
|
+
* 'Committed'` directly on a `Commitment` envelope and returns before
|
|
234
|
+
* `applyMode` is ever called (see `applyEnvelope` above), so this method is
|
|
235
|
+
* never asked to move *into* `'Committed'` — only ever *out of* it, which is
|
|
236
|
+
* exactly the case it exists to reject. Every subclass `applyMode`
|
|
237
|
+
* implementation must call this instead of assigning `this.phase` directly;
|
|
238
|
+
* the one exception is each subclass's own field initializer, which sets
|
|
239
|
+
* the starting phase before any message has been applied and can never
|
|
240
|
+
* observe `'Committed'`.
|
|
241
|
+
*/
|
|
242
|
+
protected setPhase(phase: string): void;
|
|
229
243
|
}
|
package/dist/projections/base.js
CHANGED
|
@@ -249,5 +249,23 @@ class BaseProjection {
|
|
|
249
249
|
this.anomalies.push(anomaly);
|
|
250
250
|
logging_1.logger.warn('projection anomaly', anomaly);
|
|
251
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Assign `this.phase`, guarding against regression out of the terminal
|
|
254
|
+
* `'Committed'` state — parity with macp-sdk-python's `_set_phase`
|
|
255
|
+
* (`base_projection.py:289-313`). `applyEnvelope` sets `this.phase =
|
|
256
|
+
* 'Committed'` directly on a `Commitment` envelope and returns before
|
|
257
|
+
* `applyMode` is ever called (see `applyEnvelope` above), so this method is
|
|
258
|
+
* never asked to move *into* `'Committed'` — only ever *out of* it, which is
|
|
259
|
+
* exactly the case it exists to reject. Every subclass `applyMode`
|
|
260
|
+
* implementation must call this instead of assigning `this.phase` directly;
|
|
261
|
+
* the one exception is each subclass's own field initializer, which sets
|
|
262
|
+
* the starting phase before any message has been applied and can never
|
|
263
|
+
* observe `'Committed'`.
|
|
264
|
+
*/
|
|
265
|
+
setPhase(phase) {
|
|
266
|
+
if (this.phase === 'Committed')
|
|
267
|
+
return;
|
|
268
|
+
this.phase = phase;
|
|
269
|
+
}
|
|
252
270
|
}
|
|
253
271
|
exports.BaseProjection = BaseProjection;
|
|
@@ -22,7 +22,15 @@ class DecisionProjection extends base_1.BaseProjection {
|
|
|
22
22
|
rationale: record.rationale,
|
|
23
23
|
sender: envelope.sender,
|
|
24
24
|
});
|
|
25
|
-
|
|
25
|
+
// RFC-MACP-0007 §5 rule 6: a runtime MUST reject any Proposal/
|
|
26
|
+
// Evaluation/Objection after the first accepted Vote. A replayed/
|
|
27
|
+
// retried Proposal (same proposalId, a distinct messageId that still
|
|
28
|
+
// passes applyEnvelope's message_id dedup gate) must therefore not
|
|
29
|
+
// rewind `phase` from 'Voting' back to 'Evaluation' (issue #153).
|
|
30
|
+
// Guarding on the initial phase value — mirrors macp-sdk-python's
|
|
31
|
+
// identical `if self.phase == "Proposal": self._set_phase(...)`.
|
|
32
|
+
if (this.phase === 'Proposal')
|
|
33
|
+
this.setPhase('Evaluation');
|
|
26
34
|
break;
|
|
27
35
|
}
|
|
28
36
|
case 'Evaluation': {
|
|
@@ -80,20 +88,19 @@ class DecisionProjection extends base_1.BaseProjection {
|
|
|
80
88
|
// runtime rejects any session-scoped message once the session is
|
|
81
89
|
// non-OPEN, so a `Vote` cannot legally follow a `Commitment` in
|
|
82
90
|
// accepted history. If one reaches here anyway (the caller violated
|
|
83
|
-
// the accepted-only contract — see `applyEnvelope`'s docblock),
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
// RFC-MACP-0012 `:211`); this
|
|
87
|
-
// terminality, not by a phase
|
|
88
|
-
// recorded here too, but unlike
|
|
89
|
-
// "frozen pending cross-SDK
|
|
90
|
-
//
|
|
91
|
-
// `base.ts`), this
|
|
92
|
-
//
|
|
93
|
-
// per #128's own
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
91
|
+
// the accepted-only contract — see `applyEnvelope`'s docblock),
|
|
92
|
+
// `setPhase` (see `base.ts`) is what keeps `phase` from regressing
|
|
93
|
+
// out of `'Committed'`. Note "phase" itself is not a normative MACP
|
|
94
|
+
// term (it appears once, in passing, at RFC-MACP-0012 `:211`); this
|
|
95
|
+
// guard is justified by session terminality, not by a phase
|
|
96
|
+
// specification. An anomaly would be recorded here too, but unlike
|
|
97
|
+
// five of the six sites that were "frozen pending cross-SDK
|
|
98
|
+
// agreement" (issue #126/#128, now resolved for
|
|
99
|
+
// `duplicate_task_accept`/`settled_handoff` — see `base.ts`), this
|
|
100
|
+
// one is a session-terminality phase-regression guard, not a
|
|
101
|
+
// settlement discard, and remains genuinely undecided per #128's own
|
|
102
|
+
// explicit scoping. No behavior change here.
|
|
103
|
+
this.setPhase('Voting');
|
|
97
104
|
break;
|
|
98
105
|
}
|
|
99
106
|
default:
|
|
@@ -21,7 +21,7 @@ class HandoffProjection extends base_1.BaseProjection {
|
|
|
21
21
|
sender: envelope.sender,
|
|
22
22
|
status: 'offered',
|
|
23
23
|
});
|
|
24
|
-
this.
|
|
24
|
+
this.setPhase('OfferPending');
|
|
25
25
|
break;
|
|
26
26
|
}
|
|
27
27
|
case 'HandoffContext': {
|
|
@@ -40,7 +40,7 @@ class HandoffProjection extends base_1.BaseProjection {
|
|
|
40
40
|
}
|
|
41
41
|
handoff.contextContentType = record.contentType;
|
|
42
42
|
if (this.phase === 'OfferPending')
|
|
43
|
-
this.
|
|
43
|
+
this.setPhase('ContextSharing');
|
|
44
44
|
}
|
|
45
45
|
break;
|
|
46
46
|
}
|
|
@@ -72,7 +72,7 @@ class HandoffProjection extends base_1.BaseProjection {
|
|
|
72
72
|
// (proto-registry), so this is always a real boolean once proto 0.1.6
|
|
73
73
|
// is loaded — `true` marks a runtime synthetic implicit accept.
|
|
74
74
|
handoff.implicit = record.implicit ?? false;
|
|
75
|
-
this.
|
|
75
|
+
this.setPhase('Accepted');
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
78
78
|
this.recordAnomaly({
|
|
@@ -107,7 +107,7 @@ class HandoffProjection extends base_1.BaseProjection {
|
|
|
107
107
|
if (handoff.status === 'offered' || handoff.status === 'context_sent') {
|
|
108
108
|
handoff.status = 'declined';
|
|
109
109
|
handoff.declinedBy = record.declinedBy;
|
|
110
|
-
this.
|
|
110
|
+
this.setPhase('Declined');
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
113
|
this.recordAnomaly({
|
|
@@ -38,6 +38,19 @@ export interface ProposalRejectRecord {
|
|
|
38
38
|
reason?: string;
|
|
39
39
|
sender: string;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* The three reachable `ProposalRecord.status` values, as a runtime array —
|
|
43
|
+
* cross-SDK contract pinned by the spec repo's `schemas/parity/contract.json`
|
|
44
|
+
* (`proposal_disposition.projection_status_values`, `contract_version`
|
|
45
|
+
* 1.3.0, issue #156). `satisfies readonly ProposalRecord['status'][]` links
|
|
46
|
+
* this array to the type above at compile time, and `_ProposalStatusIsFrozen`
|
|
47
|
+
* below closes the loop in the other direction — together they prove at
|
|
48
|
+
* `npm run check` time, not just in a docblock, that `status` can never hold
|
|
49
|
+
* an acceptance-shaped value like `'accepted'` (see `ProposalRecord.status`'s
|
|
50
|
+
* own docblock above for why acceptance is tracked separately). See
|
|
51
|
+
* `tests/parity/contract.test.ts`.
|
|
52
|
+
*/
|
|
53
|
+
export declare const PROPOSAL_STATUS_VALUES: readonly ["open", "rejected", "withdrawn"];
|
|
41
54
|
export declare class ProposalProjection extends BaseProjection {
|
|
42
55
|
protected readonly mode = "macp.mode.proposal.v1";
|
|
43
56
|
readonly proposals: Map<string, ProposalRecord>;
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProposalProjection = void 0;
|
|
3
|
+
exports.ProposalProjection = exports.PROPOSAL_STATUS_VALUES = void 0;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const base_1 = require("./base");
|
|
6
|
+
/**
|
|
7
|
+
* The three reachable `ProposalRecord.status` values, as a runtime array —
|
|
8
|
+
* cross-SDK contract pinned by the spec repo's `schemas/parity/contract.json`
|
|
9
|
+
* (`proposal_disposition.projection_status_values`, `contract_version`
|
|
10
|
+
* 1.3.0, issue #156). `satisfies readonly ProposalRecord['status'][]` links
|
|
11
|
+
* this array to the type above at compile time, and `_ProposalStatusIsFrozen`
|
|
12
|
+
* below closes the loop in the other direction — together they prove at
|
|
13
|
+
* `npm run check` time, not just in a docblock, that `status` can never hold
|
|
14
|
+
* an acceptance-shaped value like `'accepted'` (see `ProposalRecord.status`'s
|
|
15
|
+
* own docblock above for why acceptance is tracked separately). See
|
|
16
|
+
* `tests/parity/contract.test.ts`.
|
|
17
|
+
*/
|
|
18
|
+
exports.PROPOSAL_STATUS_VALUES = [
|
|
19
|
+
'open',
|
|
20
|
+
'rejected',
|
|
21
|
+
'withdrawn',
|
|
22
|
+
];
|
|
6
23
|
class ProposalProjection extends base_1.BaseProjection {
|
|
7
24
|
mode = constants_1.MODE_PROPOSAL;
|
|
8
25
|
proposals = new Map();
|
|
@@ -86,7 +103,7 @@ class ProposalProjection extends base_1.BaseProjection {
|
|
|
86
103
|
const proposal = this.proposals.get(record.proposalId);
|
|
87
104
|
if (proposal) {
|
|
88
105
|
proposal.status = 'rejected';
|
|
89
|
-
this.
|
|
106
|
+
this.setPhase('TerminalRejected');
|
|
90
107
|
}
|
|
91
108
|
}
|
|
92
109
|
break;
|
|
@@ -15,7 +15,7 @@ class QuorumProjection extends base_1.BaseProjection {
|
|
|
15
15
|
case 'ApprovalRequest': {
|
|
16
16
|
const record = payload;
|
|
17
17
|
this.requests.set(record.requestId, { ...record, sender: envelope.sender });
|
|
18
|
-
this.
|
|
18
|
+
this.setPhase('Voting');
|
|
19
19
|
break;
|
|
20
20
|
}
|
|
21
21
|
case 'Approve': {
|
|
@@ -33,12 +33,19 @@ export interface TaskFailRecord {
|
|
|
33
33
|
retryable: boolean;
|
|
34
34
|
sender: string;
|
|
35
35
|
}
|
|
36
|
+
export interface TaskRejectRecord {
|
|
37
|
+
taskId: string;
|
|
38
|
+
assignee: string;
|
|
39
|
+
reason?: string;
|
|
40
|
+
sender: string;
|
|
41
|
+
}
|
|
36
42
|
export declare class TaskProjection extends BaseProjection {
|
|
37
43
|
protected readonly mode = "macp.mode.task.v1";
|
|
38
44
|
readonly tasks: Map<string, TaskRecord>;
|
|
39
45
|
readonly updates: TaskUpdateRecord[];
|
|
40
46
|
readonly completions: TaskCompleteRecord[];
|
|
41
47
|
readonly failures: TaskFailRecord[];
|
|
48
|
+
readonly rejections: TaskRejectRecord[];
|
|
42
49
|
phase: 'Pending' | 'Requested' | 'InProgress' | 'Completed' | 'Failed' | 'Committed';
|
|
43
50
|
/**
|
|
44
51
|
* The **session-level** active assignment: who currently holds the session's
|
package/dist/projections/task.js
CHANGED
|
@@ -9,6 +9,7 @@ class TaskProjection extends base_1.BaseProjection {
|
|
|
9
9
|
updates = [];
|
|
10
10
|
completions = [];
|
|
11
11
|
failures = [];
|
|
12
|
+
rejections = [];
|
|
12
13
|
phase = 'Pending';
|
|
13
14
|
/**
|
|
14
15
|
* The **session-level** active assignment: who currently holds the session's
|
|
@@ -46,7 +47,7 @@ class TaskProjection extends base_1.BaseProjection {
|
|
|
46
47
|
progress: 0,
|
|
47
48
|
sender: envelope.sender,
|
|
48
49
|
});
|
|
49
|
-
this.
|
|
50
|
+
this.setPhase('Requested');
|
|
50
51
|
break;
|
|
51
52
|
}
|
|
52
53
|
case 'TaskAccept': {
|
|
@@ -90,7 +91,7 @@ class TaskProjection extends base_1.BaseProjection {
|
|
|
90
91
|
task.assignee = record.assignee;
|
|
91
92
|
task.status = 'accepted';
|
|
92
93
|
this.activeAssignment = { sender: envelope.sender, taskId: record.taskId };
|
|
93
|
-
this.
|
|
94
|
+
this.setPhase('InProgress');
|
|
94
95
|
}
|
|
95
96
|
else {
|
|
96
97
|
this.recordAnomaly({
|
|
@@ -109,6 +110,16 @@ class TaskProjection extends base_1.BaseProjection {
|
|
|
109
110
|
}
|
|
110
111
|
case 'TaskReject': {
|
|
111
112
|
const record = payload;
|
|
113
|
+
// Issue #151: unconditional audit record, matching this file's own
|
|
114
|
+
// TaskUpdate/TaskComplete/TaskFail convention (and Python's
|
|
115
|
+
// identical unconditional `self.rejections.append(...)`,
|
|
116
|
+
// task.py:186-196) — `sender` comes from the envelope, never the
|
|
117
|
+
// payload, matching the three sibling records. Deliberately does
|
|
118
|
+
// NOT fall back `assignee` to `envelope.sender` the way Python's
|
|
119
|
+
// `p.assignee or envelope.sender` does: TaskComplete/TaskFail below
|
|
120
|
+
// spread the payload's `assignee` as-is with no such fallback, and
|
|
121
|
+
// intra-SDK consistency wins over replicating Python's nuance here.
|
|
122
|
+
this.rejections.push({ ...record, sender: envelope.sender });
|
|
112
123
|
const task = this.tasks.get(record.taskId);
|
|
113
124
|
if (task)
|
|
114
125
|
task.status = 'rejected';
|
|
@@ -158,7 +169,7 @@ class TaskProjection extends base_1.BaseProjection {
|
|
|
158
169
|
if (task) {
|
|
159
170
|
task.status = 'completed';
|
|
160
171
|
task.progress = 1;
|
|
161
|
-
this.
|
|
172
|
+
this.setPhase('Completed');
|
|
162
173
|
}
|
|
163
174
|
break;
|
|
164
175
|
}
|
|
@@ -168,7 +179,7 @@ class TaskProjection extends base_1.BaseProjection {
|
|
|
168
179
|
const task = this.tasks.get(record.taskId);
|
|
169
180
|
if (task) {
|
|
170
181
|
task.status = 'failed';
|
|
171
|
-
this.
|
|
182
|
+
this.setPhase('Failed');
|
|
172
183
|
}
|
|
173
184
|
break;
|
|
174
185
|
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/watchers.js
CHANGED
|
@@ -130,7 +130,7 @@ class ModeRegistryWatcher {
|
|
|
130
130
|
const result = await gen.next();
|
|
131
131
|
await gen.return(undefined);
|
|
132
132
|
if (result.done)
|
|
133
|
-
throw new
|
|
133
|
+
throw new errors_1.MacpTransportError('stream ended before receiving a change');
|
|
134
134
|
return result.value;
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -159,7 +159,7 @@ class RootsWatcher {
|
|
|
159
159
|
const result = await gen.next();
|
|
160
160
|
await gen.return(undefined);
|
|
161
161
|
if (result.done)
|
|
162
|
-
throw new
|
|
162
|
+
throw new errors_1.MacpTransportError('stream ended before receiving a change');
|
|
163
163
|
return result.value;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
@@ -202,7 +202,7 @@ class SignalWatcher {
|
|
|
202
202
|
const result = await gen.next();
|
|
203
203
|
await gen.return(undefined);
|
|
204
204
|
if (result.done)
|
|
205
|
-
throw new
|
|
205
|
+
throw new errors_1.MacpTransportError('stream ended before receiving a signal');
|
|
206
206
|
return result.value;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
@@ -231,7 +231,7 @@ class PolicyWatcher {
|
|
|
231
231
|
const result = await gen.next();
|
|
232
232
|
await gen.return(undefined);
|
|
233
233
|
if (result.done)
|
|
234
|
-
throw new
|
|
234
|
+
throw new errors_1.MacpTransportError('stream ended before receiving a policy change');
|
|
235
235
|
return result.value;
|
|
236
236
|
}
|
|
237
237
|
}
|
|
@@ -270,7 +270,7 @@ class SessionLifecycleWatcher {
|
|
|
270
270
|
const result = await gen.next();
|
|
271
271
|
await gen.return(undefined);
|
|
272
272
|
if (result.done)
|
|
273
|
-
throw new
|
|
273
|
+
throw new errors_1.MacpTransportError('stream ended before receiving a session lifecycle event');
|
|
274
274
|
return result.value;
|
|
275
275
|
}
|
|
276
276
|
}
|