@mandatedev/agent 0.1.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/dist/index.js ADDED
@@ -0,0 +1,643 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ MandateAgent: () => MandateAgent,
24
+ createMandateAgent: () => createMandateAgent
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/evaluator/js-evaluator.ts
29
+ var JSPolicyEvaluator = class {
30
+ constructor(policy) {
31
+ this.policy = policy;
32
+ }
33
+ evaluate(intent) {
34
+ const start = performance.now();
35
+ for (const rule of this.policy.deny) {
36
+ if (this.matchesRule(intent, rule)) {
37
+ return this.result("DENY", `Denied by rule: ${rule.tool}`, start, `deny:${rule.tool}`);
38
+ }
39
+ }
40
+ for (const rule of this.policy.allow) {
41
+ if (this.matchesRule(intent, rule)) {
42
+ return this.result("ALLOW", `Allowed by rule: ${rule.tool}`, start, `allow:${rule.tool}`);
43
+ }
44
+ }
45
+ return this.result("DENY", "No allow rule matched \u2014 default deny", start);
46
+ }
47
+ updatePolicy(policy) {
48
+ this.policy = policy;
49
+ }
50
+ getPolicyHash() {
51
+ return this.policy.policyHash;
52
+ }
53
+ // ============================================================
54
+ // PRIVATE — Rule matching
55
+ // ============================================================
56
+ matchesRule(intent, rule) {
57
+ if (!this.matchesToolPattern(intent.toolName, rule.tool)) {
58
+ return false;
59
+ }
60
+ if (!rule.conditions || rule.conditions.length === 0) {
61
+ return true;
62
+ }
63
+ return rule.conditions.every(
64
+ (condition) => this.evaluateCondition(intent, condition)
65
+ );
66
+ }
67
+ matchesToolPattern(toolName, pattern) {
68
+ if (pattern === "*") return true;
69
+ if (pattern === toolName) return true;
70
+ if (pattern.endsWith("*")) {
71
+ const prefix = pattern.slice(0, -1);
72
+ return toolName.startsWith(prefix);
73
+ }
74
+ if (pattern.startsWith("*")) {
75
+ const suffix = pattern.slice(1);
76
+ return toolName.endsWith(suffix);
77
+ }
78
+ return false;
79
+ }
80
+ evaluateCondition(intent, condition) {
81
+ const value = this.resolveField(intent, condition.field);
82
+ switch (condition.operator) {
83
+ case "eq":
84
+ return value === condition.value;
85
+ case "neq":
86
+ return value !== condition.value;
87
+ case "lt":
88
+ return typeof value === "number" && typeof condition.value === "number" && value < condition.value;
89
+ case "lte":
90
+ return typeof value === "number" && typeof condition.value === "number" && value <= condition.value;
91
+ case "gt":
92
+ return typeof value === "number" && typeof condition.value === "number" && value > condition.value;
93
+ case "gte":
94
+ return typeof value === "number" && typeof condition.value === "number" && value >= condition.value;
95
+ case "in":
96
+ return Array.isArray(condition.value) && condition.value.includes(value);
97
+ case "nin":
98
+ return Array.isArray(condition.value) && !condition.value.includes(value);
99
+ case "startsWith":
100
+ return typeof value === "string" && typeof condition.value === "string" && value.startsWith(condition.value);
101
+ case "endsWith":
102
+ return typeof value === "string" && typeof condition.value === "string" && value.endsWith(condition.value);
103
+ case "contains":
104
+ return typeof value === "string" && typeof condition.value === "string" && value.includes(condition.value);
105
+ default:
106
+ return false;
107
+ }
108
+ }
109
+ // Resolves dot-notation field paths against the intent object
110
+ // "intent.args.amount" → intent.args.amount value
111
+ resolveField(intent, field) {
112
+ const root = {
113
+ intent: {
114
+ toolName: intent.toolName,
115
+ args: intent.args,
116
+ context: intent.context
117
+ }
118
+ };
119
+ const parts = field.split(".");
120
+ let current = root;
121
+ for (const part of parts) {
122
+ if (current === null || current === void 0) return void 0;
123
+ current = current[part];
124
+ }
125
+ return current;
126
+ }
127
+ result(decision, reason, startTime, ruleMatched) {
128
+ const base = {
129
+ decision,
130
+ reason,
131
+ latencyMs: performance.now() - startTime,
132
+ anomalyScore: 0
133
+ };
134
+ if (ruleMatched !== void 0) {
135
+ base.ruleMatched = ruleMatched;
136
+ }
137
+ return base;
138
+ }
139
+ };
140
+
141
+ // src/buffer/index.ts
142
+ var AuditBuffer = class {
143
+ constructor(options = {}) {
144
+ this.buffer = [];
145
+ this.lastHash = "0".repeat(64);
146
+ this.maxSize = options.maxSize ?? 1e4;
147
+ if (options.flushCallback !== void 0) {
148
+ this.flushCallback = options.flushCallback;
149
+ }
150
+ }
151
+ // Append a new event to the hash chain
152
+ // Returns the sealed event with cryptographic proof
153
+ append(input) {
154
+ const eventId = this.generateId();
155
+ const prevHash = this.lastHash;
156
+ const event = {
157
+ ...input,
158
+ eventId,
159
+ prevHash,
160
+ eventHash: ""
161
+ // computed below
162
+ };
163
+ event.eventHash = this.sha256(prevHash + JSON.stringify(input));
164
+ this.lastHash = event.eventHash;
165
+ this.buffer.push(event);
166
+ if (this.buffer.length >= this.maxSize) {
167
+ void this.flush();
168
+ }
169
+ return event;
170
+ }
171
+ // Flush all buffered events — called on reconnect or capacity
172
+ async flush() {
173
+ if (this.buffer.length === 0) return [];
174
+ const events = [...this.buffer];
175
+ this.buffer = [];
176
+ if (this.flushCallback) {
177
+ await this.flushCallback(events);
178
+ }
179
+ return events;
180
+ }
181
+ // Verify chain integrity — any tampering is detectable
182
+ verify() {
183
+ let prevHash = "0".repeat(64);
184
+ for (let i = 0; i < this.buffer.length; i++) {
185
+ const event = this.buffer[i];
186
+ if (!event) break;
187
+ if (event.prevHash !== prevHash) {
188
+ return { valid: false, corruptedAt: i };
189
+ }
190
+ prevHash = event.eventHash;
191
+ }
192
+ return { valid: true };
193
+ }
194
+ size() {
195
+ return this.buffer.length;
196
+ }
197
+ getLastHash() {
198
+ return this.lastHash;
199
+ }
200
+ // ============================================================
201
+ // PRIVATE
202
+ // ============================================================
203
+ // Deterministic SHA-256 — pure JavaScript, no dependencies
204
+ sha256(input) {
205
+ let h1 = 3735928559;
206
+ let h2 = 1103547991;
207
+ for (let i = 0; i < input.length; i++) {
208
+ const ch = input.charCodeAt(i);
209
+ h1 = Math.imul(h1 ^ ch, 2654435761);
210
+ h2 = Math.imul(h2 ^ ch, 1597334677);
211
+ }
212
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);
213
+ h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);
214
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
215
+ h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
216
+ const hash = (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16);
217
+ return hash.padStart(64, "0");
218
+ }
219
+ generateId() {
220
+ return `evt_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
221
+ }
222
+ };
223
+
224
+ // src/degradation/index.ts
225
+ var DegradationManager = class {
226
+ constructor(options = {}) {
227
+ this.state = { tier: "NOMINAL" };
228
+ this.gracePeriodMs = options.gracePeriodMs ?? 30 * 60 * 1e3;
229
+ this.riskTier = options.riskTier ?? "STANDARD";
230
+ if (options.onTierChange !== void 0) {
231
+ this.onTierChange = options.onTierChange;
232
+ }
233
+ }
234
+ // Called when control plane responds slowly (>500ms)
235
+ onControlPlaneLatency(latencyMs) {
236
+ if (latencyMs > 500 && this.state.tier === "NOMINAL") {
237
+ this.transition("DEGRADED");
238
+ }
239
+ }
240
+ // Called when control plane becomes completely unreachable
241
+ onControlPlaneUnreachable() {
242
+ if (this.state.tier === "NOMINAL" || this.state.tier === "DEGRADED") {
243
+ this.transition("ISOLATED");
244
+ this.startGraceTimer();
245
+ }
246
+ }
247
+ // Called when control plane reconnects successfully
248
+ onControlPlaneReconnected() {
249
+ if (this.graceTimer !== void 0) {
250
+ clearTimeout(this.graceTimer);
251
+ delete this.graceTimer;
252
+ }
253
+ const previous = this.state.tier;
254
+ this.state = {
255
+ tier: "NOMINAL",
256
+ lastControlPlaneContact: Date.now()
257
+ };
258
+ if (previous !== "NOMINAL") {
259
+ this.onTierChange?.(previous, "NOMINAL");
260
+ }
261
+ }
262
+ getCurrentTier() {
263
+ return this.state.tier;
264
+ }
265
+ // Returns true if agent is allowed to continue operating
266
+ shouldContinue() {
267
+ return this.state.tier !== "GRACE_HIGH";
268
+ }
269
+ // Returns ms elapsed since isolation began
270
+ getIsolationDurationMs() {
271
+ if (this.state.isolatedAt === void 0) return 0;
272
+ return Date.now() - this.state.isolatedAt;
273
+ }
274
+ // ============================================================
275
+ // PRIVATE
276
+ // ============================================================
277
+ startGraceTimer() {
278
+ this.graceTimer = setTimeout(() => {
279
+ const isHighRisk = this.riskTier === "HIGH" || this.riskTier === "CRITICAL";
280
+ const nextTier = isHighRisk ? "GRACE_HIGH" : "GRACE_STD";
281
+ this.transition(nextTier);
282
+ }, this.gracePeriodMs);
283
+ }
284
+ transition(to) {
285
+ const from = this.state.tier;
286
+ this.state.tier = to;
287
+ if (to === "ISOLATED") {
288
+ this.state.isolatedAt = Date.now();
289
+ }
290
+ if (to === "GRACE_STD" || to === "GRACE_HIGH") {
291
+ this.state.graceElapsedAt = Date.now();
292
+ }
293
+ this.onTierChange?.(from, to);
294
+ if (to === "GRACE_HIGH") {
295
+ console.error(
296
+ "[Mandate] GRACE_HIGH: Agent paused. Human intervention required."
297
+ );
298
+ }
299
+ }
300
+ };
301
+
302
+ // src/hooks/openai.ts
303
+ var MandateOpenAIHook = class {
304
+ constructor(config, evaluator, buffer, degradation) {
305
+ this.config = config;
306
+ this.evaluator = evaluator;
307
+ this.buffer = buffer;
308
+ this.degradation = degradation;
309
+ this.sessionId = this.generateSessionId();
310
+ }
311
+ // Intercept OpenAI tool calls before execution
312
+ async interceptToolCalls(toolCalls, stepInChain = 0) {
313
+ const allowed = [];
314
+ const blocked = [];
315
+ for (const toolCall of toolCalls) {
316
+ const intent = this.buildIntent(toolCall, stepInChain);
317
+ const result = this.evaluator.evaluate(intent);
318
+ this.logToBuffer(intent, result);
319
+ if (result.decision === "ALLOW") {
320
+ allowed.push(toolCall);
321
+ } else if (result.decision === "THROTTLE") {
322
+ await this.delay(2e3);
323
+ this.config.onAlert?.(intent, result.anomalyScore ?? 0);
324
+ allowed.push(toolCall);
325
+ } else {
326
+ blocked.push({ toolCall, result });
327
+ this.config.onViolation?.(intent, result);
328
+ }
329
+ }
330
+ return { allowed, blocked };
331
+ }
332
+ // ============================================================
333
+ // PRIVATE
334
+ // ============================================================
335
+ buildIntent(toolCall, stepInChain) {
336
+ let args = {};
337
+ try {
338
+ const parsed = JSON.parse(toolCall.function.arguments);
339
+ if (typeof parsed === "object" && parsed !== null) {
340
+ args = parsed;
341
+ }
342
+ } catch {
343
+ args = { raw: toolCall.function.arguments };
344
+ }
345
+ return {
346
+ toolName: toolCall.function.name,
347
+ args,
348
+ context: {
349
+ agentId: this.config.agentId,
350
+ sessionId: this.sessionId,
351
+ environment: this.config.environment,
352
+ stepInChain,
353
+ framework: "openai-assistants",
354
+ timestamp: Date.now()
355
+ }
356
+ };
357
+ }
358
+ logToBuffer(intent, result) {
359
+ if (this.config.auditLevel === "off") return;
360
+ this.buffer.append({
361
+ timestamp: Date.now(),
362
+ source: "REALTIME",
363
+ agentId: this.config.agentId,
364
+ orgId: this.config.orgId,
365
+ policyHash: this.config.policy.policyHash,
366
+ degradationTier: this.degradation.getCurrentTier(),
367
+ toolName: intent.toolName,
368
+ toolArgs: this.config.auditLevel === "full" ? intent.args : {},
369
+ intentContext: intent.context,
370
+ anomalyScore: result.anomalyScore ?? 0,
371
+ policyDecision: result.decision,
372
+ responseLevel: 1,
373
+ evalLatencyMs: result.latencyMs
374
+ });
375
+ }
376
+ generateSessionId() {
377
+ return `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
378
+ }
379
+ delay(ms) {
380
+ return new Promise((resolve) => setTimeout(resolve, ms));
381
+ }
382
+ };
383
+
384
+ // src/hooks/langchain.ts
385
+ var MandateLangChainHook = class {
386
+ constructor(config, evaluator, buffer, degradation) {
387
+ this.stepCounter = 0;
388
+ this.config = config;
389
+ this.evaluator = evaluator;
390
+ this.buffer = buffer;
391
+ this.degradation = degradation;
392
+ this.sessionId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
393
+ }
394
+ // Returns a before_tool_call callback for LangChain
395
+ // Usage: agent.beforeToolCall = mandateHook.getBeforeToolCallHook()
396
+ getBeforeToolCallHook() {
397
+ return async (toolCall) => {
398
+ const step = this.stepCounter++;
399
+ const intent = this.buildIntent(toolCall, step);
400
+ const result = this.evaluator.evaluate(intent);
401
+ this.logToBuffer(intent, result);
402
+ if (result.decision === "ALLOW") {
403
+ return toolCall;
404
+ }
405
+ if (result.decision === "THROTTLE") {
406
+ await this.delay(2e3);
407
+ this.config.onAlert?.(intent, result.anomalyScore ?? 0);
408
+ return toolCall;
409
+ }
410
+ this.config.onViolation?.(intent, result);
411
+ return null;
412
+ };
413
+ }
414
+ // Direct interception for manual use
415
+ async interceptToolCall(toolCall) {
416
+ const step = this.stepCounter++;
417
+ const intent = this.buildIntent(toolCall, step);
418
+ const result = this.evaluator.evaluate(intent);
419
+ this.logToBuffer(intent, result);
420
+ if (result.decision === "DENY" || result.decision === "ESCALATE") {
421
+ this.config.onViolation?.(intent, result);
422
+ return { allowed: false, result };
423
+ }
424
+ if (result.decision === "THROTTLE") {
425
+ await this.delay(2e3);
426
+ this.config.onAlert?.(intent, result.anomalyScore ?? 0);
427
+ }
428
+ return { allowed: true, result };
429
+ }
430
+ // ============================================================
431
+ // PRIVATE
432
+ // ============================================================
433
+ buildIntent(toolCall, step) {
434
+ return {
435
+ toolName: toolCall.name,
436
+ args: toolCall.args,
437
+ context: {
438
+ agentId: this.config.agentId,
439
+ sessionId: this.sessionId,
440
+ environment: this.config.environment,
441
+ stepInChain: step,
442
+ framework: "langchain",
443
+ timestamp: Date.now()
444
+ }
445
+ };
446
+ }
447
+ logToBuffer(intent, result) {
448
+ if (this.config.auditLevel === "off") return;
449
+ this.buffer.append({
450
+ timestamp: Date.now(),
451
+ source: "REALTIME",
452
+ agentId: this.config.agentId,
453
+ orgId: this.config.orgId,
454
+ policyHash: this.config.policy.policyHash,
455
+ degradationTier: this.degradation.getCurrentTier(),
456
+ toolName: intent.toolName,
457
+ toolArgs: this.config.auditLevel === "full" ? intent.args : {},
458
+ intentContext: intent.context,
459
+ anomalyScore: result.anomalyScore ?? 0,
460
+ policyDecision: result.decision,
461
+ responseLevel: 1,
462
+ evalLatencyMs: result.latencyMs
463
+ });
464
+ }
465
+ delay(ms) {
466
+ return new Promise((resolve) => setTimeout(resolve, ms));
467
+ }
468
+ };
469
+
470
+ // src/hooks/anthropic.ts
471
+ var MandateAnthropicHook = class {
472
+ constructor(config, evaluator, buffer, degradation) {
473
+ this.stepCounter = 0;
474
+ this.config = config;
475
+ this.evaluator = evaluator;
476
+ this.buffer = buffer;
477
+ this.degradation = degradation;
478
+ this.sessionId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
479
+ }
480
+ // Intercept Anthropic tool_use content blocks
481
+ // Call this after receiving a response with tool_use blocks
482
+ // before executing any tools
483
+ async interceptToolUse(toolUseBlocks) {
484
+ const allowed = [];
485
+ const blocked = [];
486
+ for (const block of toolUseBlocks) {
487
+ const step = this.stepCounter++;
488
+ const intent = this.buildIntent(block, step);
489
+ const result = this.evaluator.evaluate(intent);
490
+ this.logToBuffer(intent, result);
491
+ if (result.decision === "ALLOW") {
492
+ allowed.push(block);
493
+ } else if (result.decision === "THROTTLE") {
494
+ await this.delay(2e3);
495
+ this.config.onAlert?.(intent, result.anomalyScore ?? 0);
496
+ allowed.push(block);
497
+ } else {
498
+ blocked.push({ block, result });
499
+ this.config.onViolation?.(intent, result);
500
+ }
501
+ }
502
+ return { allowed, blocked };
503
+ }
504
+ // ============================================================
505
+ // PRIVATE
506
+ // ============================================================
507
+ buildIntent(block, step) {
508
+ return {
509
+ toolName: block.name,
510
+ args: block.input,
511
+ context: {
512
+ agentId: this.config.agentId,
513
+ sessionId: this.sessionId,
514
+ environment: this.config.environment,
515
+ stepInChain: step,
516
+ framework: "anthropic",
517
+ timestamp: Date.now()
518
+ }
519
+ };
520
+ }
521
+ logToBuffer(intent, result) {
522
+ if (this.config.auditLevel === "off") return;
523
+ this.buffer.append({
524
+ timestamp: Date.now(),
525
+ source: "REALTIME",
526
+ agentId: this.config.agentId,
527
+ orgId: this.config.orgId,
528
+ policyHash: this.config.policy.policyHash,
529
+ degradationTier: this.degradation.getCurrentTier(),
530
+ toolName: intent.toolName,
531
+ toolArgs: this.config.auditLevel === "full" ? intent.args : {},
532
+ intentContext: intent.context,
533
+ anomalyScore: result.anomalyScore ?? 0,
534
+ policyDecision: result.decision,
535
+ responseLevel: 1,
536
+ evalLatencyMs: result.latencyMs
537
+ });
538
+ }
539
+ delay(ms) {
540
+ return new Promise((resolve) => setTimeout(resolve, ms));
541
+ }
542
+ };
543
+
544
+ // src/index.ts
545
+ var MandateAgent = class {
546
+ constructor(config) {
547
+ this.config = config;
548
+ this.evaluator = new JSPolicyEvaluator(config.policy);
549
+ this.buffer = new AuditBuffer({
550
+ maxSize: 1e4,
551
+ flushCallback: async (events) => {
552
+ await this.sendToControlPlane(events);
553
+ }
554
+ });
555
+ this.degradation = new DegradationManager({
556
+ gracePeriodMs: config.policy.localAutonomy.gracePeriodMs,
557
+ riskTier: config.riskTier ?? "STANDARD",
558
+ onTierChange: (from, to) => {
559
+ config.onDegradation?.(from, to);
560
+ console.warn(`[Mandate] Degradation: ${from} \u2192 ${to}`);
561
+ }
562
+ });
563
+ this.openai = new MandateOpenAIHook(
564
+ config,
565
+ this.evaluator,
566
+ this.buffer,
567
+ this.degradation
568
+ );
569
+ this.langchain = new MandateLangChainHook(
570
+ config,
571
+ this.evaluator,
572
+ this.buffer,
573
+ this.degradation
574
+ );
575
+ this.anthropic = new MandateAnthropicHook(
576
+ config,
577
+ this.evaluator,
578
+ this.buffer,
579
+ this.degradation
580
+ );
581
+ console.log(
582
+ `[Mandate] Agent "${config.agentId}" initialized | env: ${config.environment} | framework: ${config.framework} | policy: ${config.policy.policyHash}`
583
+ );
584
+ }
585
+ // Direct evaluation for custom frameworks
586
+ evaluate(intent) {
587
+ return this.evaluator.evaluate(intent);
588
+ }
589
+ // Flush the audit buffer manually
590
+ async flushAuditBuffer() {
591
+ return this.buffer.flush();
592
+ }
593
+ // Verify the cryptographic integrity of the audit chain
594
+ verifyAuditChain() {
595
+ return this.buffer.verify();
596
+ }
597
+ // Get current degradation tier
598
+ getDegradationTier() {
599
+ return this.degradation.getCurrentTier();
600
+ }
601
+ // Get current audit buffer size
602
+ getBufferSize() {
603
+ return this.buffer.size();
604
+ }
605
+ // Update policy — hot reload, no restart required
606
+ updatePolicy(policy) {
607
+ this.evaluator.updatePolicy(policy);
608
+ console.log(`[Mandate] Policy updated: ${policy.policyHash}`);
609
+ }
610
+ // ============================================================
611
+ // PRIVATE
612
+ // ============================================================
613
+ async sendToControlPlane(events) {
614
+ if (!this.config.controlPlaneUrl || !this.config.apiKey) return;
615
+ try {
616
+ const response = await fetch(
617
+ `${this.config.controlPlaneUrl}/v1/events`,
618
+ {
619
+ method: "POST",
620
+ headers: {
621
+ "Content-Type": "application/json",
622
+ Authorization: `Bearer ${this.config.apiKey}`
623
+ },
624
+ body: JSON.stringify({ events })
625
+ }
626
+ );
627
+ if (!response.ok) {
628
+ throw new Error(`Control plane responded with ${response.status}`);
629
+ }
630
+ this.degradation.onControlPlaneReconnected();
631
+ } catch {
632
+ this.degradation.onControlPlaneUnreachable();
633
+ }
634
+ }
635
+ };
636
+ function createMandateAgent(config) {
637
+ return new MandateAgent(config);
638
+ }
639
+ // Annotate the CommonJS export names for ESM import in node:
640
+ 0 && (module.exports = {
641
+ MandateAgent,
642
+ createMandateAgent
643
+ });