macp-sdk-typescript 0.11.0 → 0.12.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 +371 -0
- package/README.md +1 -1
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +2 -1
- package/dist/agent/participant.d.ts +47 -4
- package/dist/agent/participant.js +88 -10
- package/dist/agent/strategies.js +23 -7
- package/dist/agent/transports.d.ts +19 -1
- package/dist/agent/transports.js +108 -66
- package/dist/auth.d.ts +15 -4
- package/dist/auth.js +23 -7
- package/dist/base-session.js +13 -3
- package/dist/client.js +58 -15
- package/dist/commitment-hash.d.ts +33 -3
- package/dist/commitment-hash.js +39 -5
- package/dist/decision.d.ts +1 -0
- package/dist/decision.js +11 -9
- package/dist/envelope.js +9 -1
- package/dist/handoff.d.ts +1 -0
- package/dist/handoff.js +19 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +18 -7
- package/dist/projections/base.d.ts +71 -14
- package/dist/projections/base.js +83 -12
- package/dist/projections/decision.js +23 -3
- package/dist/projections/handoff.js +39 -16
- package/dist/projections/proposal.js +16 -2
- package/dist/projections/quorum.js +13 -0
- package/dist/projections/task.d.ts +27 -4
- package/dist/projections/task.js +44 -13
- package/dist/proposal.d.ts +1 -0
- package/dist/proposal.js +2 -2
- package/dist/proto-registry.d.ts +69 -3
- package/dist/proto-registry.js +83 -5
- package/dist/quorum.d.ts +1 -0
- package/dist/quorum.js +4 -4
- package/dist/task.d.ts +1 -0
- package/dist/task.js +24 -11
- package/dist/types.d.ts +14 -7
- package/dist/validation.d.ts +14 -0
- package/dist/validation.js +39 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,41 @@ 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.12.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.11.0...v0.12.0) (2026-09-30)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### ⚠ BREAKING CHANGES
|
|
11
|
+
|
|
12
|
+
* **auth:** Auth.devAgent sets expectedSender to enforce sender identity client-side ([#133](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/133))
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **parity:** add isCanonicalCommitmentHash + anomaly constant exports ([bbde8d2](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/bbde8d2f72b6fa2d1dc9024bafa587a21243d051))
|
|
17
|
+
* **projections:** rename TaskCompletionRecord/TaskFailureRecord ([#142](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/142)) ([84008e1](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/84008e1700304814fe17093ae35c9046aab553ea))
|
|
18
|
+
* **projections:** rename TaskProjection.isComplete to isCompleted ([#141](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/141)) ([3239ae6](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/3239ae63df50b25064b51bdee93d397af2ed904e))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **agent:** Participant terminal-on-cancel, teardown on every run() exit, tri-state isStopped, guarded rollback pop ([#113](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/113)) ([e1a7de4](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/e1a7de486c9ce6d23c249811a98ba99a15814a9b))
|
|
24
|
+
* **agent:** retry a transient NOT_FOUND on subscribe ([#100](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/100)) ([#101](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/101)) ([ffb0251](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/ffb02514aaaeb9351bf465c00e808833536d3568))
|
|
25
|
+
* **auth:** Auth.devAgent sets expectedSender to enforce sender identity client-side ([#133](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/133)) ([cc0f344](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/cc0f344f2cbb4cf4d59e17fbe4d043cc6f9eebac))
|
|
26
|
+
* **client:** map stream inline errors and registry gRPC statuses to MacpAckError ([#118](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/118)) ([28d4c52](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/28d4c527c324469848ce90a9199b7318970dd071))
|
|
27
|
+
* **commitment-hash:** supersedes: null now hashes as absent, matching macp-sdk-python ([#114](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/114)) ([6e15b9f](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/6e15b9fbc2fc61699970ed30276fd2e249152f08))
|
|
28
|
+
* **index:** drop _resetLoggingForTests from public surface; correct pagination/ListRoots docs ([#112](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/112)) ([99c2f4a](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/99c2f4a67c5200a60f3d7facfbec0ab0dc08eb85))
|
|
29
|
+
* **parity:** re-vendor contract.json for contract_version 1.1.1 ([#129](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/129)) ([459e795](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/459e7959a5eabaa32008b8750bbf33c972e151a3)), closes [#125](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/125)
|
|
30
|
+
* **parity:** re-vendor contract.json for contract_version 1.2.0 ([#136](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/136)) ([8ef1ab1](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/8ef1ab1861e8e871cf3284ee3e125fceba7e2691)), closes [#135](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/135)
|
|
31
|
+
* **projections:** gate TaskComplete/TaskFail phase transitions on task existence ([#120](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/120)) ([41f9010](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/41f90109df032c8072052232cd4501d2bbda0fed)), closes [#111](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/111)
|
|
32
|
+
* **projections:** gate three more phase transitions on entity existence ([#123](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/123)) ([866490a](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/866490a332353049064596371dd1e05b4598062f)), closes [#119](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/119)
|
|
33
|
+
* **projections:** guard QuorumProjection.setBallot on request existence ([#127](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/127)) ([e3b75aa](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/e3b75aa265e019610cfd7b0d0446a38a93437d01)), closes [#121](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/121)
|
|
34
|
+
* **projections:** unfreeze 5 of 6 ProjectionAnomalyKind sites ([#126](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/126), [#128](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/128)) ([#134](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/134)) ([a99668c](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/a99668cf8977309c91c0390f5c0967ad80c2786b))
|
|
35
|
+
* **proto-registry:** stop coercing legacy-JSON Contribute value ([#124](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/124)) ([#130](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/130)) ([02bbe90](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/02bbe90c48824e82e0436d315dd0582d057ffec2))
|
|
36
|
+
* **proto-registry:** stop misdecoding canonical Contribute payloads as JSON ([#110](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/110)) ([26dddb6](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/26dddb61eb7ff163c23ecbd6e96c2abedfab150c))
|
|
37
|
+
* **sessions,agent,auth:** thread auth through start(), default identities, validate strategy output ([#116](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/116)) ([4c633e0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/4c633e02f11bc5f6a8995346b9b4cdc0213003c0))
|
|
38
|
+
* **strategies:** exclude REVIEW evaluations from majorityVoter ratio ([#124](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/124)) ([#131](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/131)) ([b52c7f2](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/b52c7f2744bd5841a023461a4009c411a9514b75))
|
|
39
|
+
* **validation:** enforce no-fall-through session-id rule, reject NaN confidence, normalize decision.ts wire case ([#115](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/115)) ([df1c6a2](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/df1c6a2c966f2f5f88937b3b2fcc2a160edbd987))
|
|
40
|
+
* **validation:** stop rejecting empty/omitted intent, instructions, action, summary ([#124](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/124)) ([#132](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/132)) ([aa157ee](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/aa157eeff8d284c1cc727c7cb0d73a86f41ab35b))
|
|
41
|
+
|
|
7
42
|
## [0.11.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.10.0...v0.11.0) (2026-09-22)
|
|
8
43
|
|
|
9
44
|
|
|
@@ -69,6 +104,22 @@ project uses [Semantic Versioning](https://semver.org/).
|
|
|
69
104
|
pass `schemaVersion` explicitly get going forward. Pass
|
|
70
105
|
`{ schemaVersion: 1 }` or `{ schemaVersion: 2 }` explicitly to keep the
|
|
71
106
|
old fail-open behavior.
|
|
107
|
+
* **auth:** `Auth.devAgent(agentId)` now also sets `expectedSender: agentId`
|
|
108
|
+
on the returned `AuthConfig` (issue #124 item 4). The runtime's dev
|
|
109
|
+
fallback already authenticates the gRPC connection as the bearer value
|
|
110
|
+
(`agentId`) and unconditionally refuses a mismatched `sender` for dev
|
|
111
|
+
credentials (`macp-runtime/src/server.rs:229-231`, no insecure/dev
|
|
112
|
+
exemption) — this SDK now enforces the same guarantee client-side instead
|
|
113
|
+
of surfacing the runtime's rejection late and confusingly. A bootstrap or
|
|
114
|
+
caller whose `agent_id`/credential diverges from the `sender`/
|
|
115
|
+
`participant_id` it actually sends now fails on the first typed
|
|
116
|
+
handler-driven action (e.g. `acceptTask`, `vote`) with
|
|
117
|
+
`MacpIdentityMismatchError`, instead of only failing server-side. The
|
|
118
|
+
initiator's `SessionStart`/kickoff path is unaffected (it passes no
|
|
119
|
+
explicit `sender`), as is the generic `actions.send` escape hatch (which
|
|
120
|
+
still only fails server-side). A caller that genuinely needs one
|
|
121
|
+
credential reused across multiple senders should use
|
|
122
|
+
`Auth.bearer(token, senderHint)` (the legacy two-arg form) instead.
|
|
72
123
|
|
|
73
124
|
### Features
|
|
74
125
|
|
|
@@ -98,6 +149,326 @@ project uses [Semantic Versioning](https://semver.org/).
|
|
|
98
149
|
legitimate retry with a corrected payload was silently absorbed as a
|
|
99
150
|
redelivery and the envelope's effect was lost forever.
|
|
100
151
|
|
|
152
|
+
### Added
|
|
153
|
+
|
|
154
|
+
- **All five mode sessions' `start()` now accept a per-call
|
|
155
|
+
`auth?: AuthConfig`** (issue #108, part 2 of 2 — 4B), matching every other
|
|
156
|
+
action method on these classes. Previously `start()` alone ignored a
|
|
157
|
+
per-call `auth` on `DecisionSession`/`ProposalSession`/`TaskSession`/
|
|
158
|
+
`HandoffSession`/`QuorumSession`, resolving the sender only against the
|
|
159
|
+
session/client-level credential — so a caller passing a conflicting
|
|
160
|
+
per-call `auth.expectedSender` never got the identity-mismatch guard
|
|
161
|
+
(RFC-MACP-0004 §4) that every other method already enforced.
|
|
162
|
+
`BaseSession.start()` already accepted and threaded a per-call `auth`
|
|
163
|
+
before this change; see the `BaseSession.start()` validation entry below
|
|
164
|
+
for what actually changed there in 4B.
|
|
165
|
+
- **`ProjectionAnomalyKind` gains two new, cross-SDK-agreed kinds:
|
|
166
|
+
`duplicate_task_accept` and `settled_handoff`** (issue #126/#128;
|
|
167
|
+
`macp-sdk-python` landed its half in PR #95). `TaskProjection` now records
|
|
168
|
+
a `duplicate_task_accept` anomaly when a `TaskAccept` for a task it has a
|
|
169
|
+
`TaskRequest` on file for is discarded because another task already holds
|
|
170
|
+
the session's one assignee slot (RFC-MACP-0009 §5 rules 3/3a).
|
|
171
|
+
`HandoffProjection` now records a `settled_handoff` anomaly when a
|
|
172
|
+
`HandoffAccept`/`HandoffDecline` targets a `handoff_id` that already
|
|
173
|
+
settled as accepted or declined (RFC-MACP-0010 §5 rule 4). Both new
|
|
174
|
+
constants (`ANOMALY_DUPLICATE_TASK_ACCEPT`/`ANOMALY_SETTLED_HANDOFF`)
|
|
175
|
+
export from the package root alongside the existing pair. A `TaskAccept`/
|
|
176
|
+
`HandoffAccept`/`HandoffDecline` for an *unknown* `task_id`/`handoff_id`
|
|
177
|
+
still records no anomaly — that determination (not caller misuse) is
|
|
178
|
+
unchanged by this release. This is purely additive observability: no
|
|
179
|
+
change to `phase`, `tasks`, or `handoffs` state itself at any of these
|
|
180
|
+
sites. `DecisionProjection`'s late-`Vote`-after-`Commitment` site remains
|
|
181
|
+
the one still-open, undecided case (per #128's own explicit scoping) —
|
|
182
|
+
unaffected by this change.
|
|
183
|
+
|
|
184
|
+
### Changed
|
|
185
|
+
|
|
186
|
+
- **BREAKING (test-only surface): `_resetLoggingForTests` is no longer part
|
|
187
|
+
of the package's public export surface.** (issue #109) It was reachable
|
|
188
|
+
only via `src/index.ts`'s `export * from './logging'` wildcard; that line
|
|
189
|
+
is now a named re-export listing `logger`, `configureLogging`, `LogLevel`,
|
|
190
|
+
and `LogSink`. Because `package.json`'s `exports` map exposes only `"."`,
|
|
191
|
+
this makes the helper unreachable from the published package entirely (no
|
|
192
|
+
submodule fallback) — accepted, since it is test-only by name and by
|
|
193
|
+
purpose, and `configureLogging` already covers every legitimate caller
|
|
194
|
+
need.
|
|
195
|
+
- **`validateSessionId` now enforces the runtime's actual no-fall-through
|
|
196
|
+
rule** (issue #108, part 1 of 2 — 4A). A UUID-**shaped** string (36 chars,
|
|
197
|
+
hyphens at 8-13-18-23, hex-only) is now validated strictly as a lowercase
|
|
198
|
+
v4/v7 UUID and never reinterpreted as base64url. An uppercase UUID, a
|
|
199
|
+
lowercase v1 UUID, the nil UUID, or a UUID with a bad variant nibble now
|
|
200
|
+
throws `MacpSessionError` client-side — all were already rejected by the
|
|
201
|
+
runtime, so nothing that previously *worked* stops working, but a caller
|
|
202
|
+
relying on the old, looser client-side check now gets the rejection
|
|
203
|
+
earlier. Ports `macp-sdk-python`'s two-regex no-fall-through structure.
|
|
204
|
+
- **`DecisionSession.evaluate`/`raiseObjection`/`vote` now put the
|
|
205
|
+
normalized (uppercased/lowercased) value on the wire, not the caller's
|
|
206
|
+
original case** (issue #108, part 1 of 2 — 4A).
|
|
207
|
+
`validateVote`/`validateRecommendation`/`validateSeverity` each return a
|
|
208
|
+
normalized string; the three call sites in `decision.ts` previously
|
|
209
|
+
discarded it. A consumer that string-compares an un-normalized value
|
|
210
|
+
(e.g. `'approve'` instead of `'APPROVE'`) sees a different value on the
|
|
211
|
+
wire; every in-repo projection already normalizes case itself, so no
|
|
212
|
+
projection assertion is affected by this change.
|
|
213
|
+
- **An empty/missing `bearerToken` now throws `MacpSdkError`, not a bare
|
|
214
|
+
`Error`** (issue #108, part 2 of 2 — 4B). `validateAuth` (and therefore
|
|
215
|
+
`metadataFromAuth`, reached from every authenticated RPC) previously threw
|
|
216
|
+
a plain `Error('bearerToken is required')`, which is not `instanceof
|
|
217
|
+
MacpSdkError` — escaping the documented `catch (e) { if (e instanceof
|
|
218
|
+
MacpSdkError) ... }` pattern from both SDKs' error-handling docs. Message
|
|
219
|
+
text unchanged.
|
|
220
|
+
- **`BaseSession.start()` now runs the same full `validateSessionStart`
|
|
221
|
+
check as the five built-in mode sessions, not a partial check** (issue
|
|
222
|
+
#108, part 2 of 2 — 4B). Previously this documented ext-mode extension
|
|
223
|
+
point validated only participant count and `maxSuspendMs`, so an empty
|
|
224
|
+
`intent`, an empty/duplicate `participants` array, or an out-of-range
|
|
225
|
+
`ttlMs` reached the wire unvalidated from a custom mode built on
|
|
226
|
+
`BaseSession` — the weakest-validated mode in the SDK. All five now
|
|
227
|
+
reject client-side, matching every built-in mode session.
|
|
228
|
+
- **BREAKING (narrows an exception type): `send()` now throws `MacpAckError`,
|
|
229
|
+
not `MacpTransportError`, for a gRPC `ALREADY_EXISTS`/`FAILED_PRECONDITION`;
|
|
230
|
+
same for `registerExtMode`/`unregisterExtMode`/`promoteMode`/
|
|
231
|
+
`registerPolicy`/`unregisterPolicy` on `FAILED_PRECONDITION`** (issue #107).
|
|
232
|
+
These are application-level rejections the runtime couldn't express as a
|
|
233
|
+
normal Ack, not transport faults — `MacpAckError` (`failure.code`
|
|
234
|
+
`'SESSION_ALREADY_EXISTS'` / `'POLICY_DENIED'` / `'FAILED_PRECONDITION'`
|
|
235
|
+
respectively) is the correct, Python-parity model
|
|
236
|
+
(`client.py:442-452`, `_map_registry_mutation_error` at `client.py:347-362`).
|
|
237
|
+
Code today catching `MacpTransportError` around these calls for these
|
|
238
|
+
specific statuses stops matching (`MacpAckError` extends `MacpSdkError`
|
|
239
|
+
directly, not `MacpTransportError`); every other gRPC status on these RPCs,
|
|
240
|
+
and every status on every other RPC, is unaffected. A knock-on effect on
|
|
241
|
+
`retrySend()`: a `FAILED_PRECONDITION` `send()` was previously retried to
|
|
242
|
+
exhaustion (no code filter on `MacpTransportError`) and surfaced as
|
|
243
|
+
`MacpRetryError`; it now surfaces immediately as `MacpAckError`, since
|
|
244
|
+
`POLICY_DENIED` is not in `DEFAULT_RETRY_POLICY.retryableCodes` — strictly
|
|
245
|
+
more correct (neither condition is retryable) and no longer masks the real
|
|
246
|
+
error behind a generic "retries exhausted."
|
|
247
|
+
- **`TaskProjection.isComplete(taskId)` renamed to `isCompleted(taskId)`**
|
|
248
|
+
(issue #138, cross-SDK naming decision at
|
|
249
|
+
multiagentcoordinationprotocol#135). Every other `is*` predicate in this
|
|
250
|
+
SDK is past-participle (`isFailed`, `isAccepted`, `isTerminallyRejected`,
|
|
251
|
+
`isDeclined`); `isComplete` was the outlier, and `macp-sdk-python` has
|
|
252
|
+
always spelled this `is_completed`. The old name remains available — see
|
|
253
|
+
`### Deprecated` below.
|
|
254
|
+
- **`TaskCompletionRecord` renamed to `TaskCompleteRecord`, and
|
|
255
|
+
`TaskFailureRecord` renamed to `TaskFailRecord`** (issue #138, cross-SDK
|
|
256
|
+
naming decision at multiagentcoordinationprotocol#135). Both now mirror
|
|
257
|
+
their triggering `TaskComplete`/`TaskFail` message types the way their
|
|
258
|
+
sibling `TaskUpdateRecord` already mirrors `TaskUpdate`, and match
|
|
259
|
+
`macp-sdk-python` and `macp-runtime`'s own names for the same records. The
|
|
260
|
+
old names remain available — see `### Deprecated` below.
|
|
261
|
+
|
|
262
|
+
### Deprecated
|
|
263
|
+
|
|
264
|
+
- **`TaskProjection.isComplete(taskId)`** remains available as a
|
|
265
|
+
`@deprecated` alias for `isCompleted(taskId)`; use `isCompleted()` instead.
|
|
266
|
+
Scheduled for removal in 0.13.0.
|
|
267
|
+
- **`TaskCompletionRecord`/`TaskFailureRecord`** remain available as
|
|
268
|
+
`@deprecated` type aliases for `TaskCompleteRecord`/`TaskFailRecord`
|
|
269
|
+
respectively. Scheduled for removal in 0.13.0.
|
|
270
|
+
|
|
271
|
+
### Fixed
|
|
272
|
+
|
|
273
|
+
- **`validateConfidence` now rejects `NaN`** (issue #108, part 1 of 2 — 4A).
|
|
274
|
+
`NaN < 0` and `NaN > 1.0` are both `false`, so a bare range check silently
|
|
275
|
+
accepted `NaN` — verified by execution before this fix. `±Infinity` was
|
|
276
|
+
already rejected (incidentally); this also rejects it explicitly via
|
|
277
|
+
`Number.isFinite`, matching this file's own `ttlMs`/`maxSuspendMs` idiom.
|
|
278
|
+
- **`commitmentHash`/`canonicalizeCommitmentPayload`: `supersedes: null` now
|
|
279
|
+
hashes as absent, matching `macp-sdk-python`** (issue #105). `supersedes`
|
|
280
|
+
is a proto3 message-typed field with only present/absent wire states;
|
|
281
|
+
`null` is the idiomatic in-language representation of "absent" (e.g. under
|
|
282
|
+
a `defaults: true` protobufjs/proto-loader decode, or a payload
|
|
283
|
+
round-tripped through JSON). Previously `supersedes: null` took the
|
|
284
|
+
*present* branch and hashed identically to an explicit
|
|
285
|
+
`{ sessionId: '', commitmentHash: '' }`, producing a different digest than
|
|
286
|
+
`macp-sdk-python` computes for the same logical commitment. The predicate
|
|
287
|
+
changed from `p.supersedes !== undefined` to `p.supersedes != null`
|
|
288
|
+
(deliberately loose — catches `null` and `undefined` only, so `0`, `''`,
|
|
289
|
+
`false`, and other falsy-but-not-nullish values still take the present
|
|
290
|
+
branch, unaffected). Not a protocol MINOR bump: the hashing `LABEL` and
|
|
291
|
+
frozen field set are unchanged — this corrects a projection bug, not the
|
|
292
|
+
algorithm. Any digest a caller already computed by feeding `null` was
|
|
293
|
+
already wrong (Python never reproduced it), so there is no
|
|
294
|
+
correct-value regression, but the fix is a security/audit-relevant
|
|
295
|
+
behavior change on this SDK's own output.
|
|
296
|
+
- **`Participant` lifecycle: `SessionCancel` now reaches `onTerminal`, and
|
|
297
|
+
teardown runs on every exit from `run()`, not just an explicit `stop()`**
|
|
298
|
+
(issue #106). Three independent bugs in `src/agent/participant.ts`:
|
|
299
|
+
- A runtime-issued `SessionCancel` never fired `onTerminal` at all — no
|
|
300
|
+
built-in projection maps it to a terminal phase, so the phase-driven
|
|
301
|
+
dispatch path had nothing to trigger on. `Participant` now recognizes
|
|
302
|
+
`SessionCancel` directly as a fallback when the phase path doesn't fire,
|
|
303
|
+
dispatching `{ state: 'Cancelled' }`. Against the current `macp-runtime`,
|
|
304
|
+
this fallback's practical reach is `processEvent()` callers and
|
|
305
|
+
cross-SDK parity with `macp-sdk-python`'s identical fallback — the
|
|
306
|
+
streamed `run()` path never observes a `SessionCancel` at all today,
|
|
307
|
+
since `cancel_session` stores it as `EntryKind::Internal` and
|
|
308
|
+
`get_incoming_after` filters strictly to `EntryKind::Incoming`;
|
|
309
|
+
cancellation surfaces via `session_lifecycle_bus`/`WatchSessions`
|
|
310
|
+
instead.
|
|
311
|
+
- `run()`'s `finally` only cleared an internal flag; the transport
|
|
312
|
+
subscription and the cancel-callback HTTP listener were torn down
|
|
313
|
+
exclusively inside `stop()`. A normal terminal exit, or a transport
|
|
314
|
+
simply running out of messages, leaked both — a long-lived agent
|
|
315
|
+
process running many sessions sequentially leaked one gRPC stream
|
|
316
|
+
subscription and one listening TCP socket per completed session.
|
|
317
|
+
Teardown now runs on every exit from `run()`.
|
|
318
|
+
- `isStopped` computed `!running`, so it read `true` immediately after
|
|
319
|
+
construction, before `run()` had ever been called. Fixed by tracking
|
|
320
|
+
three independent states (`running` / `terminal` / `stopRequested`)
|
|
321
|
+
instead of one flag — deliberately **not** a single latch copied from
|
|
322
|
+
`macp-sdk-python`, because that would make a `Participant` single-use
|
|
323
|
+
after any `stop()`, breaking this SDK's own documented and tested
|
|
324
|
+
restart contract (issue #66): `stop()` mid-stream, then a second
|
|
325
|
+
`run()` on the same instance, must resume rather than refuse. Only a
|
|
326
|
+
genuinely *terminal* outcome is single-use; a `stop()`-only exit is a
|
|
327
|
+
resumable pause.
|
|
328
|
+
- **`BaseProjection`'s rollback pop is now guarded by reference identity**
|
|
329
|
+
(issue #106, item 4): it no longer unconditionally pops the last
|
|
330
|
+
`transcript` entry on a failed decode. `BaseProjection` is documented
|
|
331
|
+
subclassable API; a third-party subclass whose `applyMode` pushes its own
|
|
332
|
+
entry onto `transcript` before throwing would previously have had that
|
|
333
|
+
entry silently removed instead of the envelope actually under
|
|
334
|
+
application — data corruption strictly worse than the bug the rollback
|
|
335
|
+
itself fixes. Mirrors `macp-sdk-python`'s identical guard and its own
|
|
336
|
+
documented trade-off in this exact scenario.
|
|
337
|
+
- **Identity fields on `Task`/`Handoff` actions now default to the resolved
|
|
338
|
+
sender when omitted or empty, matching `macp-sdk-python`** (issue #108,
|
|
339
|
+
part 2 of 2 — 4B): `TaskSession.acceptTask`/`rejectTask`/`completeTask`/
|
|
340
|
+
`failTask`'s `assignee`, and `HandoffSession.acceptHandoff`'s `acceptedBy`/
|
|
341
|
+
`decline`'s `declinedBy`, are now optional and fall back to the caller's
|
|
342
|
+
authenticated identity (`input.field || resolvedSender` — `||`, not `??`,
|
|
343
|
+
since an explicit empty string is also meant to fall back). Previously
|
|
344
|
+
these were required fields passed straight through with no default, unlike
|
|
345
|
+
the Python SDK (`task.py:299,323,391,430`, `handoff.py:247,271`).
|
|
346
|
+
- **`HandoffSession.addContext`'s `contentType` now defaults to
|
|
347
|
+
`'application/octet-stream'` when omitted**, matching `macp-sdk-python`
|
|
348
|
+
(`handoff.py:210`) (issue #108, part 2 of 2 — 4B). Previously `contentType`
|
|
349
|
+
was a required field with no default.
|
|
350
|
+
- **`evaluationHandler`/`votingHandler` now validate a strategy's output
|
|
351
|
+
before dispatching it** (issue #108, part 2 of 2 — 4B). Both previously
|
|
352
|
+
passed a custom `EvaluationStrategy`/`VotingStrategy`'s raw
|
|
353
|
+
`recommendation`/`confidence`/`vote` straight to `ctx.actions.*` with no
|
|
354
|
+
validation, so a buggy strategy (an out-of-enum recommendation, a `NaN`
|
|
355
|
+
confidence, an out-of-enum vote) failed later and less legibly, from
|
|
356
|
+
inside the session rather than at the handler that produced the bad
|
|
357
|
+
value. Both handlers now reuse this SDK's own `validateRecommendation`/
|
|
358
|
+
`validateConfidence`/`validateVote` (throwing the documented
|
|
359
|
+
`MacpSessionError`) and dispatch the validators' normalized return value.
|
|
360
|
+
- **`MacpStream`'s inline-error path was reading a shape a real decode never
|
|
361
|
+
produces, silently dropping every inline application-level error** (issue
|
|
362
|
+
#107). `StreamSessionResponse.response` is a proto3 `oneof`; under this
|
|
363
|
+
file's own `@grpc/proto-loader` options (`oneofs: true`), the decoded
|
|
364
|
+
object exposes the payload directly as `chunk.envelope`/`chunk.error`, with
|
|
365
|
+
`chunk.response` set to the oneof's *arm name as a string* (`'envelope'` or
|
|
366
|
+
`'error'`) — not a nested object. The old code read
|
|
367
|
+
`chunk?.response?.error`, which indexes a string and is always `undefined`
|
|
368
|
+
on every message that has ever crossed this stream; the corresponding unit
|
|
369
|
+
test only ever passed because it emitted the same fictional
|
|
370
|
+
`{ response: { error } }` shape by hand rather than a real decode. Fixed to
|
|
371
|
+
read `chunk.error` directly, and each inline error is now also logged at
|
|
372
|
+
`warn` (it previously produced no log line anywhere).
|
|
373
|
+
- **`TaskProjection.phase` no longer advances to `'Completed'`/`'Failed'` for
|
|
374
|
+
a `TaskComplete`/`TaskFail` naming an unknown `task_id`** (issue #111).
|
|
375
|
+
Both `this.phase` assignments sat outside the `if (task) { ... }` guard
|
|
376
|
+
that already gated every other per-task field mutation in the same
|
|
377
|
+
`applyMode` cases, so a message for a `task_id` this projection never saw
|
|
378
|
+
a `TaskRequest` for still flipped the session-level `phase` to a terminal
|
|
379
|
+
state even though no task actually completed or failed. Moved both
|
|
380
|
+
assignments inside their sibling `if (task)` block, matching the guard
|
|
381
|
+
already correct on `TaskAccept` (issue #71/#70) and on
|
|
382
|
+
`HandoffProjection`'s analogous `phase` transitions.
|
|
383
|
+
- **Three more `phase`-transition-outside-guard sites, same bug shape as
|
|
384
|
+
issue #111, found during that fix's verification** (issue #119):
|
|
385
|
+
- `ProposalProjection`'s `Reject` case moved `this.phase =
|
|
386
|
+
'TerminalRejected'` inside the sibling `if (proposal) { ... }` guard. A
|
|
387
|
+
terminal `Reject` for an unknown `proposalId` no longer advances `phase`
|
|
388
|
+
— which matters beyond bookkeeping, since `'TerminalRejected'` is a
|
|
389
|
+
`TERMINAL_PHASES` member in `src/agent/participant.ts`, so the bug could
|
|
390
|
+
end a live `Participant`'s `run()` loop for a session that never
|
|
391
|
+
actually terminated.
|
|
392
|
+
- `HandoffProjection`'s `HandoffContext` case moved its `phase` transition
|
|
393
|
+
(`'OfferPending'` → `'ContextSharing'`) inside the sibling `if (handoff)
|
|
394
|
+
{ ... }` guard, matching `HandoffAccept`/`HandoffDecline`, which were
|
|
395
|
+
already correct.
|
|
396
|
+
- `DecisionProjection`'s `Vote` case gained a new existence guard (none
|
|
397
|
+
existed before): `if (!this.proposals.has(record.proposalId)) break;`,
|
|
398
|
+
per RFC-MACP-0007 §5 rule 2 ("`Evaluation`, `Objection`, and `Vote` MUST
|
|
399
|
+
reference an existing `proposal_id`"). Previously a `Vote` for an unknown
|
|
400
|
+
`proposalId` fabricated a `votes` `Map` entry and flipped `phase` to
|
|
401
|
+
`'Voting'` — the fabricated entry also inflated `voteTotals()`'s and
|
|
402
|
+
`majorityWinner()`'s denominators, able to flip a real proposal from
|
|
403
|
+
winner to non-winner in a close tally.
|
|
404
|
+
|
|
405
|
+
All three sites' `rejections`/audit-array-style writes remain unconditional
|
|
406
|
+
(append-only logs, matching the runtime), so query methods reading from
|
|
407
|
+
them (`isTerminallyRejected`, `hasTerminalRejection`) can still report
|
|
408
|
+
`true` for an unknown id even though `phase` no longer moves — intentional,
|
|
409
|
+
not a residual gap.
|
|
410
|
+
- **`QuorumProjection.setBallot` no longer fabricates a `ballots` entry for an
|
|
411
|
+
unknown `request_id`** (issue #121, found during issue #119's plan-review
|
|
412
|
+
sweep). RFC-MACP-0011 §5 rule 3 requires a ballot (`Approve`/`Reject`/
|
|
413
|
+
`Abstain`) to reference the Session's accepted `request_id`; there was no
|
|
414
|
+
check against `this.requests` before creating or extending a `ballots` Map
|
|
415
|
+
entry, so an unfiltered/multi-session transcript could make
|
|
416
|
+
`votedSenders()` and `approvalCount()`/`rejectionCount()`/
|
|
417
|
+
`abstentionCount()` report on a `request_id` that was never opened, and a
|
|
418
|
+
second such ballot from the same sender could fire a spurious
|
|
419
|
+
`duplicate_ballot` anomaly against it. Unlike the three sites above, this
|
|
420
|
+
bug never touched `phase` — `QuorumProjection.phase` is set only by
|
|
421
|
+
`ApprovalRequest` and by `Commitment` handling in `BaseProjection` — so the
|
|
422
|
+
fix is a single existence guard at the top of `setBallot`, with no phase
|
|
423
|
+
component.
|
|
424
|
+
- **`ProtoRegistry.decodeMultiRoundContribute` no longer coerces a legacy-JSON
|
|
425
|
+
`Contribute` payload's `value` to a string** (issue #124). Previously
|
|
426
|
+
`String(parsed.value ?? '')` made an absent `value` key indistinguishable
|
|
427
|
+
from a genuine empty string, and stringified any non-string JSON value
|
|
428
|
+
(`123` decoded to `'123'`, `null` decoded to `''`). The legacy-JSON decode
|
|
429
|
+
path now passes `parsed.value` through exactly as `JSON.parse` produced
|
|
430
|
+
it — `undefined` stays `undefined`, `null` stays `null`, a number stays a
|
|
431
|
+
number. The canonical-protobuf decode path is unaffected (its `value` is
|
|
432
|
+
always a `string`, per the proto schema).
|
|
433
|
+
- **`majorityVoter` no longer counts `REVIEW` evaluations in its approval
|
|
434
|
+
ratio** (issue #124). RFC-MACP-0007 §4 states `REVIEW` evaluations "do not
|
|
435
|
+
block or approve a proposal; they serve as informational analysis records
|
|
436
|
+
only" — a `REVIEW` was nonetheless lowering the ratio's denominator, so a
|
|
437
|
+
proposal with one `APPROVE` and one `REVIEW` voted at ratio `0.5` instead
|
|
438
|
+
of `1.0`. The ratio's denominator is now the `decisive` evaluations
|
|
439
|
+
(everything except `REVIEW`, case-insensitive); `shouldVote` now returns
|
|
440
|
+
`false` for an evaluation set of only `REVIEW`s (no decisive evaluation to
|
|
441
|
+
vote on) instead of voting `REJECT` at ratio `0`. `BLOCK` and `REJECT`
|
|
442
|
+
remain in the denominator — they are stances, not informational-only
|
|
443
|
+
records.
|
|
444
|
+
- **`intent`, `instructions`, `action`, and `summary` no longer rejected when
|
|
445
|
+
empty or omitted** (issue #124). `SessionStart.intent`,
|
|
446
|
+
`TaskSession.requestTask`'s `instructions`, and
|
|
447
|
+
`QuorumSession.requestApproval`'s `action`/`summary` are proto3 singular
|
|
448
|
+
`string` fields — implicit presence means an omitted value and an explicit
|
|
449
|
+
`''` serialize to identical bytes, so a client-side "required, non-empty"
|
|
450
|
+
check rejected a payload the runtime would accept and no runtime-side check
|
|
451
|
+
could ever distinguish. `intent` also has an explicit normative rule
|
|
452
|
+
(RFC-MACP-0001 §7.1: a runtime "MUST NOT reject a SessionStart solely
|
|
453
|
+
because intent is empty"). Every other `validateRequiredField` call
|
|
454
|
+
site — `taskId`, `title`, `requestId`, `proposalId`, `option`, `handoffId`,
|
|
455
|
+
`targetParticipant`, `modeVersion`, `configurationVersion` — is unaffected
|
|
456
|
+
and still rejects an empty value.
|
|
457
|
+
|
|
458
|
+
### Documentation
|
|
459
|
+
|
|
460
|
+
- **Pagination memory caveat** (issue #109): `docs/api/client.md`'s
|
|
461
|
+
`listSessions` and `listSessionsPage` entries now state plainly that while
|
|
462
|
+
`macp-runtime` ≥ 0.7.0 (current: 0.8.3) implements real server-side
|
|
463
|
+
pagination, `listSessions()` itself still accumulates every page into one
|
|
464
|
+
in-memory array regardless of `pageSize` — callers who need bounded
|
|
465
|
+
memory should call `listSessionsPage()` directly.
|
|
466
|
+
- **`ListRoots` wording** (issue #109): `docs/guides/streaming.md` no
|
|
467
|
+
longer says the runtime "serves `ListRoots`," which reads as "returns
|
|
468
|
+
real data" — reworded to state plainly that the runtime always returns an
|
|
469
|
+
empty root list. `docs/api/client.md`'s `listRoots` entry gains the same
|
|
470
|
+
statement, which it previously lacked entirely.
|
|
471
|
+
|
|
101
472
|
## [0.10.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.9.0...v0.10.0) (2026-09-01)
|
|
102
473
|
|
|
103
474
|
|
package/README.md
CHANGED
|
@@ -158,7 +158,7 @@ await session.commit({ action: 'task.completed', authorityScope: 'lead', reason:
|
|
|
158
158
|
|
|
159
159
|
// Projection queries
|
|
160
160
|
session.projection.progressOf('t1'); // 1.0
|
|
161
|
-
session.projection.
|
|
161
|
+
session.projection.isCompleted('t1'); // true
|
|
162
162
|
session.projection.activeTasks(); // []
|
|
163
163
|
```
|
|
164
164
|
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export * from './dispatcher';
|
|
|
4
4
|
export * from './participant';
|
|
5
5
|
export * from './strategies';
|
|
6
6
|
export * from './runner';
|
|
7
|
-
export { GrpcTransportAdapter, HttpTransportAdapter, type TransportAdapter, type HttpPollingConfig, } from './transports';
|
|
7
|
+
export { GrpcTransportAdapter, HttpTransportAdapter, DEFAULT_SUBSCRIBE_RETRY_POLICY, type TransportAdapter, type HttpPollingConfig, type SubscribeRetryPolicy, } from './transports';
|
package/dist/agent/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.HttpTransportAdapter = exports.GrpcTransportAdapter = void 0;
|
|
17
|
+
exports.DEFAULT_SUBSCRIBE_RETRY_POLICY = exports.HttpTransportAdapter = exports.GrpcTransportAdapter = void 0;
|
|
18
18
|
__exportStar(require("./types"), exports);
|
|
19
19
|
__exportStar(require("./cancel-callback"), exports);
|
|
20
20
|
__exportStar(require("./dispatcher"), exports);
|
|
@@ -24,3 +24,4 @@ __exportStar(require("./runner"), exports);
|
|
|
24
24
|
var transports_1 = require("./transports");
|
|
25
25
|
Object.defineProperty(exports, "GrpcTransportAdapter", { enumerable: true, get: function () { return transports_1.GrpcTransportAdapter; } });
|
|
26
26
|
Object.defineProperty(exports, "HttpTransportAdapter", { enumerable: true, get: function () { return transports_1.HttpTransportAdapter; } });
|
|
27
|
+
Object.defineProperty(exports, "DEFAULT_SUBSCRIBE_RETRY_POLICY", { enumerable: true, get: function () { return transports_1.DEFAULT_SUBSCRIBE_RETRY_POLICY; } });
|
|
@@ -39,8 +39,10 @@ export interface ParticipantConfig {
|
|
|
39
39
|
/**
|
|
40
40
|
* Bind a cancel-callback HTTP endpoint (RFC-0001 §7.2 Option A) when
|
|
41
41
|
* this participant's event loop starts. The server is closed
|
|
42
|
-
* automatically
|
|
43
|
-
*
|
|
42
|
+
* automatically on any exit from {@link Participant.run} — an explicit
|
|
43
|
+
* {@link Participant.stop}, a terminal outcome, or the transport running
|
|
44
|
+
* out of messages. Parity with python-sdk's bootstrap `cancel_callback`
|
|
45
|
+
* field.
|
|
44
46
|
*/
|
|
45
47
|
cancelCallback?: {
|
|
46
48
|
host: string;
|
|
@@ -64,7 +66,23 @@ export declare class Participant {
|
|
|
64
66
|
private readonly modeVersion?;
|
|
65
67
|
private readonly configurationVersion?;
|
|
66
68
|
private readonly policyVersion?;
|
|
69
|
+
/** Whether the event loop is currently inside {@link run}. */
|
|
67
70
|
private running;
|
|
71
|
+
/**
|
|
72
|
+
* Latching: set once a terminal result is dispatched (a terminal phase,
|
|
73
|
+
* or the {@code SessionCancel} fallback in {@link processMessage}). A
|
|
74
|
+
* terminal `Participant` is single-use — {@link run} refuses to
|
|
75
|
+
* re-enter, because the projection is resolved and the runtime will
|
|
76
|
+
* accept nothing further for this session.
|
|
77
|
+
*/
|
|
78
|
+
private terminal;
|
|
79
|
+
/**
|
|
80
|
+
* The cooperative cancel flag {@link stop} sets and {@link run} clears
|
|
81
|
+
* on entry — the loop's break predicate. Distinct from {@link terminal}:
|
|
82
|
+
* a `stop()`-exited, non-terminal `Participant` is a resumable pause
|
|
83
|
+
* (see {@link isStopped}), not single-use.
|
|
84
|
+
*/
|
|
85
|
+
private stopRequested;
|
|
68
86
|
private lastPhase;
|
|
69
87
|
private cancelCallbackServer?;
|
|
70
88
|
private readonly cancelCallbackConfig?;
|
|
@@ -74,7 +92,12 @@ export declare class Participant {
|
|
|
74
92
|
on(messageType: string, handler: MessageHandler): Participant;
|
|
75
93
|
onPhaseChange(phase: string, handler: PhaseChangeHandler): Participant;
|
|
76
94
|
onTerminal(handler: TerminalHandler): Participant;
|
|
77
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* `true` after a terminal outcome (single-use from here on), or while a
|
|
97
|
+
* `stop()` request is pending/has taken effect on a `Participant` whose
|
|
98
|
+
* loop has not (yet) been resumed by a later {@link run}. A `stop()`
|
|
99
|
+
* exit is resumable — see {@link run} and {@link terminal}'s own doc.
|
|
100
|
+
*/
|
|
78
101
|
get isStopped(): boolean;
|
|
79
102
|
run(): Promise<void>;
|
|
80
103
|
/**
|
|
@@ -87,10 +110,30 @@ export declare class Participant {
|
|
|
87
110
|
private buildHandlerContext;
|
|
88
111
|
/** Returns true if a terminal state was reached. */
|
|
89
112
|
private processMessage;
|
|
113
|
+
/**
|
|
114
|
+
* Idempotent teardown of everything {@link run} started: the transport
|
|
115
|
+
* subscription and the cancel-callback HTTP listener, if any. Called
|
|
116
|
+
* from both {@link stop} and every exit from {@link run}'s loop (issue
|
|
117
|
+
* #106.2) — a normal terminal exit or a transport running out of
|
|
118
|
+
* messages used to leak both. A rejecting `transport.stop()` is caught
|
|
119
|
+
* rather than propagated, so a transport fault on teardown cannot mask
|
|
120
|
+
* a clean session outcome as a thrown error from {@link run}.
|
|
121
|
+
*/
|
|
122
|
+
private teardown;
|
|
123
|
+
/**
|
|
124
|
+
* Request that {@link run}'s loop stop. This SDK's {@link TransportAdapter}
|
|
125
|
+
* has no `cancel()` — `stop()` on the transport is the only thing that can
|
|
126
|
+
* wake a loop suspended awaiting the next envelope, so teardown (including
|
|
127
|
+
* the transport) runs here unconditionally, not just the flag. Safe to
|
|
128
|
+
* call whether or not `run()` is currently active; does not itself flip
|
|
129
|
+
* {@link running} — only `run()`'s own loop exit does that, since it is
|
|
130
|
+
* the only place that actually knows the loop has left.
|
|
131
|
+
*/
|
|
90
132
|
stop(): Promise<void>;
|
|
91
133
|
/**
|
|
92
134
|
* Attach a running cancel-callback HTTP server to this participant.
|
|
93
|
-
* The server is closed automatically
|
|
135
|
+
* The server is closed automatically on any exit from {@link run} — see
|
|
136
|
+
* {@link teardown}.
|
|
94
137
|
* Parity with python-sdk's `Participant.attach_cancel_callback_server`.
|
|
95
138
|
*/
|
|
96
139
|
attachCancelCallbackServer(server: CancelCallbackServer): void;
|