@yanlinglabs/winter-agent-sdk 0.0.1 → 0.0.2

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 CHANGED
@@ -1,3 +1,9 @@
1
+ import {
2
+ deliveryUncertain2,
3
+ refused2,
4
+ unavailable2
5
+ } from "./index-h1tryj38.js";
6
+
1
7
  // src/query.ts
2
8
  import { randomUUID } from "node:crypto";
3
9
 
@@ -349,6 +355,134 @@ function resolveKeychainServiceForProfile(brand, env, hostSetKeychainService) {
349
355
  return suffixed.length <= 64 ? suffixed : brand.keychainService;
350
356
  }
351
357
 
358
+ // src/protocol/messaging.ts
359
+ var MESSAGING_CONTROL_SUBTYPES = {
360
+ listReachable: "messaging.list_reachable",
361
+ deliver: "messaging.deliver",
362
+ steerChild: "messaging.steer_child",
363
+ resumeChild: "messaging.resume_child",
364
+ subscribeIdle: "messaging.subscribe_idle",
365
+ senderClass: "messaging.sender_class",
366
+ readNotifications: "messaging.read_notifications",
367
+ idleNotice: "messaging.idle_notice"
368
+ };
369
+ var MESSAGING_HOST_REQUEST_SUBTYPES = [
370
+ MESSAGING_CONTROL_SUBTYPES.listReachable,
371
+ MESSAGING_CONTROL_SUBTYPES.deliver,
372
+ MESSAGING_CONTROL_SUBTYPES.steerChild,
373
+ MESSAGING_CONTROL_SUBTYPES.resumeChild,
374
+ MESSAGING_CONTROL_SUBTYPES.subscribeIdle,
375
+ MESSAGING_CONTROL_SUBTYPES.senderClass,
376
+ MESSAGING_CONTROL_SUBTYPES.readNotifications
377
+ ];
378
+ var MESSAGING_RUNTIME_REQUEST_SUBTYPES = [MESSAGING_CONTROL_SUBTYPES.idleNotice];
379
+ var MESSAGING_CONTROL_SUBTYPE_LIST = Object.values(MESSAGING_CONTROL_SUBTYPES);
380
+ function isRecord(v) {
381
+ return typeof v === "object" && v !== null && !Array.isArray(v);
382
+ }
383
+ var RUNTIME_OBJECT_KINDS = ["session", "agent"];
384
+ var RUNTIME_KINDS = ["claude-agent", "winter-agent"];
385
+ var PERMISSION_CLASS_LABELS = ["prompts", "bypasses", "unknown"];
386
+ var DELIVERY_STATUSES = [
387
+ "delivered",
388
+ "queued",
389
+ "resumed_and_delivered",
390
+ "held",
391
+ "subscribed",
392
+ "delivery_uncertain",
393
+ "refused",
394
+ "ambiguous",
395
+ "not_found",
396
+ "unavailable"
397
+ ];
398
+ function isRuntimeAddress(v) {
399
+ if (!isRecord(v))
400
+ return false;
401
+ if (!RUNTIME_OBJECT_KINDS.includes(v.objectKind))
402
+ return false;
403
+ if (!RUNTIME_KINDS.includes(v.runtimeKind))
404
+ return false;
405
+ if (typeof v.winterSessionId !== "string" || v.winterSessionId.length === 0)
406
+ return false;
407
+ if (v.objectKind === "agent" && (typeof v.childId !== "string" || v.childId.length === 0))
408
+ return false;
409
+ return true;
410
+ }
411
+ function isGlobalAgentMessage(v) {
412
+ if (!isRecord(v))
413
+ return false;
414
+ if (typeof v.messageId !== "string" || v.messageId.length === 0)
415
+ return false;
416
+ if (!isRuntimeAddress(v.from) || !isRuntimeAddress(v.to))
417
+ return false;
418
+ if (typeof v.body !== "string")
419
+ return false;
420
+ if (typeof v.notifyWhenIdle !== "boolean")
421
+ return false;
422
+ if (typeof v.hopCount !== "number")
423
+ return false;
424
+ if (!PERMISSION_CLASS_LABELS.includes(v.senderPermissionClass))
425
+ return false;
426
+ return true;
427
+ }
428
+ function isDeliveryOutcome(v) {
429
+ if (!isRecord(v))
430
+ return false;
431
+ if (!DELIVERY_STATUSES.includes(v.status))
432
+ return false;
433
+ if (typeof v.messageId !== "string")
434
+ return false;
435
+ if (v.status === "ambiguous" && !Array.isArray(v.candidates))
436
+ return false;
437
+ if (v.status === "unavailable" && typeof v.retryable !== "boolean")
438
+ return false;
439
+ return true;
440
+ }
441
+ function isListedRuntimeObjectArray(v) {
442
+ return Array.isArray(v) && v.every((row) => isRecord(row) && typeof row.address === "string" && RUNTIME_OBJECT_KINDS.includes(row.objectKind) && isRecord(row.capabilities));
443
+ }
444
+ function isPermissionClassLabel(v) {
445
+ return typeof v === "string" && PERMISSION_CLASS_LABELS.includes(v);
446
+ }
447
+ function isMessagingDeliverRequest(v) {
448
+ return isRecord(v) && isGlobalAgentMessage(v.message);
449
+ }
450
+ function isMessagingChildRequest(v) {
451
+ return isRecord(v) && typeof v.id === "string" && v.id.length > 0 && isGlobalAgentMessage(v.message);
452
+ }
453
+ function isNotificationRecord(v) {
454
+ return isRecord(v) && typeof v.notification_id === "string" && typeof v.origin === "string" && typeof v.queued_at === "string" && typeof v.content === "string";
455
+ }
456
+ function isMessagingNotificationsPage(v) {
457
+ return isRecord(v) && Array.isArray(v.notifications) && v.notifications.every(isNotificationRecord) && typeof v.remaining === "number";
458
+ }
459
+ function isMessagingIdleNoticePayload(v) {
460
+ return isRecord(v) && typeof v.subscriberSessionId === "string" && isNotificationRecord(v.notice);
461
+ }
462
+ function isMessagingReadNotificationsRequest(v) {
463
+ if (!isRecord(v))
464
+ return false;
465
+ if (v.subscriberSessionId !== undefined && typeof v.subscriberSessionId !== "string")
466
+ return false;
467
+ if (v.max !== undefined && (typeof v.max !== "number" || !Number.isFinite(v.max) || v.max < 0))
468
+ return false;
469
+ return true;
470
+ }
471
+ function isMessagingSubscribeIdleRequest(v) {
472
+ if (!isRecord(v))
473
+ return false;
474
+ if (typeof v.id !== "string" || v.id.length === 0)
475
+ return false;
476
+ if (typeof v.messageId !== "string" || v.messageId.length === 0)
477
+ return false;
478
+ if (v.subscriberSessionId !== undefined && typeof v.subscriberSessionId !== "string")
479
+ return false;
480
+ return true;
481
+ }
482
+ function resolveFacetTarget(sessionId, id, parse, buildChild) {
483
+ return parse(id) ?? buildChild(sessionId, id);
484
+ }
485
+
352
486
  // src/query.ts
353
487
  var DEFAULT_MAX_BUFFER_SIZE = 1024 * 1024;
354
488
  var KILL_GRACE_MS = 50;
@@ -819,6 +953,7 @@ function query(args) {
819
953
  }
820
954
  }
821
955
  }
956
+ const idleNoticeHandlers = new Set;
822
957
  const gen = iterate();
823
958
  gen.interrupt = async () => {
824
959
  await sendControlRequest("interrupt", { scope: "turn" });
@@ -841,6 +976,85 @@ function query(args) {
841
976
  gen.setPermissionMode = async (mode) => {
842
977
  await sendControlRequest("set_permission_mode", mode);
843
978
  };
979
+ async function deliveryCall(subtype, payload, messageId) {
980
+ let answer;
981
+ try {
982
+ answer = await sendControlRequest(subtype, payload);
983
+ } catch (err) {
984
+ const code = err instanceof WinterRpcError ? err.code : "";
985
+ const message = err instanceof Error ? err.message : String(err);
986
+ if (code === "invalid_messaging_request")
987
+ return refused2(messageId, message);
988
+ if (code === "messaging_unavailable")
989
+ return unavailable2(messageId, false, message);
990
+ return deliveryUncertain2(messageId, `'${subtype}' failed: ${message}`);
991
+ }
992
+ return isDeliveryOutcome(answer) ? answer : deliveryUncertain2(messageId, `the runtime returned a malformed delivery outcome for '${subtype}'`);
993
+ }
994
+ gen.messaging = {
995
+ async listReachable() {
996
+ const payload = await sendControlRequest(MESSAGING_CONTROL_SUBTYPES.listReachable, undefined).catch(() => {
997
+ return;
998
+ });
999
+ return isListedRuntimeObjectArray(payload) ? payload : [];
1000
+ },
1001
+ deliver(msg) {
1002
+ const request = { message: msg };
1003
+ return deliveryCall(MESSAGING_CONTROL_SUBTYPES.deliver, request, msg.messageId);
1004
+ },
1005
+ steerChild(id, msg) {
1006
+ const request = { id, message: msg };
1007
+ return deliveryCall(MESSAGING_CONTROL_SUBTYPES.steerChild, request, msg.messageId);
1008
+ },
1009
+ resumeChild(id, msg) {
1010
+ const request = { id, message: msg };
1011
+ return deliveryCall(MESSAGING_CONTROL_SUBTYPES.resumeChild, request, msg.messageId);
1012
+ },
1013
+ subscribeIdle(id, opts) {
1014
+ const request = {
1015
+ id,
1016
+ messageId: opts.messageId,
1017
+ ...opts.subscriberSessionId !== undefined ? { subscriberSessionId: opts.subscriberSessionId } : {}
1018
+ };
1019
+ return deliveryCall(MESSAGING_CONTROL_SUBTYPES.subscribeIdle, request, opts.messageId);
1020
+ },
1021
+ async senderClass() {
1022
+ const payload = await sendControlRequest(MESSAGING_CONTROL_SUBTYPES.senderClass, undefined).catch(() => {
1023
+ return;
1024
+ });
1025
+ const label = typeof payload === "object" && payload !== null ? payload.senderClass : undefined;
1026
+ return isPermissionClassLabel(label) ? label : "unknown";
1027
+ },
1028
+ async readNotifications(opts) {
1029
+ const request = {
1030
+ ...opts?.subscriberSessionId !== undefined ? { subscriberSessionId: opts.subscriberSessionId } : {},
1031
+ ...opts?.max !== undefined ? { max: opts.max } : {}
1032
+ };
1033
+ const payload = await sendControlRequest(MESSAGING_CONTROL_SUBTYPES.readNotifications, request).catch(() => {
1034
+ return;
1035
+ });
1036
+ return isMessagingNotificationsPage(payload) ? payload : { notifications: [], remaining: 0 };
1037
+ },
1038
+ onIdleNotice(handler) {
1039
+ idleNoticeHandlers.add(handler);
1040
+ return () => {
1041
+ idleNoticeHandlers.delete(handler);
1042
+ };
1043
+ }
1044
+ };
1045
+ controlRequestHandlers.set(MESSAGING_CONTROL_SUBTYPES.idleNotice, async (payload) => {
1046
+ if (!isMessagingIdleNoticePayload(payload)) {
1047
+ return { ok: false, error: { code: "invalid_idle_notice", message: "messaging.idle_notice requires { subscriberSessionId: string, notice: NotificationRecord }" } };
1048
+ }
1049
+ for (const handler of [...idleNoticeHandlers]) {
1050
+ try {
1051
+ handler(payload);
1052
+ } catch (err) {
1053
+ console.error(`winter: onIdleNotice handler threw for notification ${payload.notice.notification_id}: ${err instanceof Error ? err.message : String(err)} -- the notice is still queued for readNotifications()`);
1054
+ }
1055
+ }
1056
+ return { ok: true, payload: { delivered: idleNoticeHandlers.size } };
1057
+ });
844
1058
  gen.rewindFiles = async (userMessageId, options) => {
845
1059
  const payload = await sendControlRequest("rewind_files", { user_message_id: userMessageId, ...options?.dryRun !== undefined ? { dry_run: options.dryRun } : {} });
846
1060
  if (typeof payload !== "object" || payload === null || typeof payload.canRewind !== "boolean") {
@@ -2136,6 +2350,10 @@ export {
2136
2350
  FIRST_PARTY_ORIGINATORS,
2137
2351
  HOOK_EVENTS,
2138
2352
  InvalidBrandError,
2353
+ MESSAGING_CONTROL_SUBTYPES,
2354
+ MESSAGING_CONTROL_SUBTYPE_LIST,
2355
+ MESSAGING_HOST_REQUEST_SUBTYPES,
2356
+ MESSAGING_RUNTIME_REQUEST_SUBTYPES,
2139
2357
  OVERLAY_NEVER_KEYS,
2140
2358
  PROJECT_PERMISSIVE_KEYS,
2141
2359
  PROTOCOL_VERSION,
@@ -2167,6 +2385,18 @@ export {
2167
2385
  getSessionInfo,
2168
2386
  getSessionMessages,
2169
2387
  getSubagentMessages,
2388
+ isDeliveryOutcome,
2389
+ isGlobalAgentMessage,
2390
+ isListedRuntimeObjectArray,
2391
+ isMessagingChildRequest,
2392
+ isMessagingDeliverRequest,
2393
+ isMessagingIdleNoticePayload,
2394
+ isMessagingNotificationsPage,
2395
+ isMessagingReadNotificationsRequest,
2396
+ isMessagingSubscribeIdleRequest,
2397
+ isNotificationRecord,
2398
+ isPermissionClassLabel,
2399
+ isRuntimeAddress,
2170
2400
  isUnset,
2171
2401
  isWinterMcpServerInstance,
2172
2402
  listSessions,
@@ -2177,6 +2407,7 @@ export {
2177
2407
  query,
2178
2408
  renameSession,
2179
2409
  resolveBrand,
2410
+ resolveFacetTarget,
2180
2411
  resolveKeychainServiceForProfile,
2181
2412
  resolveRuntimeExecutable,
2182
2413
  resolveSettings,
@@ -0,0 +1,119 @@
1
+ import type { PermissionMode } from "../permissions/types.js";
2
+ export type RuntimeKind = "claude-agent" | "winter-agent";
3
+ export type RuntimeObjectKind = "session" | "agent";
4
+ export interface RuntimeAddress {
5
+ objectKind: RuntimeObjectKind;
6
+ runtimeKind: RuntimeKind;
7
+ winterSessionId: string;
8
+ backendSessionId?: string;
9
+ parentWinterSessionId?: string;
10
+ childId?: string;
11
+ }
12
+ export declare function serializeRuntimeAddress(addr: RuntimeAddress): string;
13
+ export interface ListedRuntimeObject {
14
+ address: string;
15
+ name?: string;
16
+ objectKind: RuntimeObjectKind;
17
+ runtimeKind: RuntimeKind;
18
+ status: "starting" | "running" | "idle" | "exited" | "unavailable" | "archived";
19
+ mode: string;
20
+ cwd?: string;
21
+ capabilities: {
22
+ message: boolean;
23
+ resume: boolean;
24
+ notifyWhenIdle: boolean;
25
+ reply: boolean;
26
+ };
27
+ }
28
+ export type DeliveryOutcome = {
29
+ status: "delivered";
30
+ messageId: string;
31
+ } | {
32
+ status: "queued";
33
+ messageId: string;
34
+ } | {
35
+ status: "resumed_and_delivered";
36
+ messageId: string;
37
+ } | {
38
+ status: "held";
39
+ messageId: string;
40
+ reason: string;
41
+ } | {
42
+ status: "subscribed";
43
+ messageId: string;
44
+ } | {
45
+ status: "delivery_uncertain";
46
+ messageId: string;
47
+ deliveryMayHaveOccurred: true;
48
+ reason: string;
49
+ } | {
50
+ status: "refused";
51
+ messageId: string;
52
+ reason: string;
53
+ } | {
54
+ status: "ambiguous";
55
+ messageId: string;
56
+ candidates: ListedRuntimeObject[];
57
+ } | {
58
+ status: "not_found";
59
+ messageId: string;
60
+ reason: string;
61
+ } | {
62
+ status: "unavailable";
63
+ messageId: string;
64
+ retryable: boolean;
65
+ reason: string;
66
+ };
67
+ export interface GlobalAgentMessage {
68
+ messageId: string;
69
+ from: RuntimeAddress;
70
+ fromGeneration: number;
71
+ to: RuntimeAddress;
72
+ toGeneration: number;
73
+ body: string;
74
+ summary?: string;
75
+ notifyWhenIdle: boolean;
76
+ createdAt: number;
77
+ expiresAt: number;
78
+ hopCount: number;
79
+ originToolCallId?: string;
80
+ senderPermissionClass: "prompts" | "bypasses" | "unknown";
81
+ }
82
+ export type ChildLikeStatus = "running" | "completed" | "stopped" | "failed";
83
+ export interface ChildLikeRecord {
84
+ id: string;
85
+ parentSessionId: string;
86
+ name?: string;
87
+ permission: {
88
+ effectiveMode: PermissionMode;
89
+ };
90
+ }
91
+ export interface ChildLike {
92
+ readonly record: ChildLikeRecord;
93
+ status(): ChildLikeStatus;
94
+ steer(msg: GlobalAgentMessage): Promise<DeliveryOutcome>;
95
+ resume(msg: GlobalAgentMessage): Promise<DeliveryOutcome>;
96
+ }
97
+ export interface RuntimeMessagingAdapter {
98
+ listReachable(scope: {
99
+ parent?: RuntimeAddress;
100
+ }): Promise<ListedRuntimeObject[]>;
101
+ steerChild(addr: RuntimeAddress, msg: GlobalAgentMessage): Promise<DeliveryOutcome>;
102
+ resumeChild(addr: RuntimeAddress, msg: GlobalAgentMessage): Promise<DeliveryOutcome>;
103
+ deliverToSession(addr: RuntimeAddress, msg: GlobalAgentMessage): Promise<DeliveryOutcome>;
104
+ subscribeIdle(addr: RuntimeAddress, req: {
105
+ messageId: string;
106
+ }): Promise<DeliveryOutcome>;
107
+ senderPermissionClass(addr: RuntimeAddress): Promise<"prompts" | "bypasses" | "unknown">;
108
+ }
109
+ export interface MessagingRouterSeam {
110
+ allocateMessageId(senderSessionId: string, toolUseId: string): string;
111
+ recordOutcome(messageId: string, outcome: DeliveryOutcome): void;
112
+ lookupOutcome(messageId: string): DeliveryOutcome | undefined;
113
+ children(): ChildLike[];
114
+ }
115
+ export interface FakeMessagingRouterSeam extends MessagingRouterSeam {
116
+ readonly outcomes: Map<string, DeliveryOutcome>;
117
+ setChildren(children: ChildLike[]): void;
118
+ }
119
+ export declare function createFakeMessagingRouterSeam(): FakeMessagingRouterSeam;
@@ -0,0 +1,13 @@
1
+ import { type RuntimeAddress, type RuntimeKind } from "./adapter.js";
2
+ export declare const REFERENCE_RUNTIME_KIND: RuntimeKind;
3
+ export type ToFieldValidation = {
4
+ ok: true;
5
+ } | {
6
+ ok: false;
7
+ message: string;
8
+ };
9
+ export declare function validateToField(to: unknown): ToFieldValidation;
10
+ export declare function buildSessionAddress(winterSessionId: string): RuntimeAddress;
11
+ export declare function buildChildAddress(parentWinterSessionId: string, childId: string): RuntimeAddress;
12
+ export declare function parseRuntimeAddress(serialized: string): RuntimeAddress | undefined;
13
+ export declare function sameAddress(a: RuntimeAddress, b: RuntimeAddress): boolean;
@@ -0,0 +1,43 @@
1
+ /** The tag a rendered turn is wrapped in. One literal, so nothing spells it twice. */
2
+ export declare const AGENT_MESSAGE_TAG = "agent-message";
3
+ /**
4
+ * Fix r2 (N2): the escape that makes the attribution frame mean something.
5
+ *
6
+ * THE FINDING. A rendered turn is TEXT in the receiving session's input, and the runtime concatenates
7
+ * sender-chosen text into it. `body` and `summary` are model-authored on the `SendMessage` path
8
+ * (straight off the tool input), so a subagent could close the runtime's frame and open a second one
9
+ * naming an address it does not own with `sender-permission-class="bypasses"` — measured, delivered
10
+ * intact, and syntactically indistinguishable to the receiving model from the real one. The `from`
11
+ * field was never forgeable; the FRAME was, which made the label decorative.
12
+ *
13
+ * WHAT IS ESCAPED, and nothing more: the two sequences that can end or start a frame (`</tag` and
14
+ * `<tag`) and the double quote that can close an attribute value. A real message never contains the
15
+ * first two, and the quote is escaped only inside attribute values, so "a legitimate message arrives
16
+ * altered" costs a bare `"` in a summary and nothing else. The transformation is VISIBLE rather than
17
+ * silent (`&lt;` / `&quot;`), so a receiver reading a message that genuinely discusses this syntax
18
+ * still sees what was written.
19
+ *
20
+ * WHAT IT IS NOT. Lexical escaping makes the count of attributions in a turn honest; it does not make
21
+ * attribution structural. A protocol-level frame kind — where the receiver's DECODER carries the
22
+ * attribution and a body is inert data whatever it contains — is the real fix, and is recorded as a
23
+ * carry. Until then this is what keeps the label from being trivially imitable.
24
+ */
25
+ export declare function escapeAttributionText(value: string): string;
26
+ /** The same, plus the attribute-value quote — for anything interpolated INSIDE the opening tag. */
27
+ export declare function escapeAttributionAttribute(value: string): string;
28
+ /**
29
+ * Fix r2 (N5): the queue key the FACET files and drains notifications under, built structurally.
30
+ *
31
+ * DELIBERATELY NOT the bare session id. A session's own model drains `notifications.drain(sessionId)`
32
+ * through its `ReadNotifications` tool, and a drain REMOVES — so one key would have whichever side
33
+ * read first silently eat the other's notices.
34
+ *
35
+ * `RESERVED_NOTIFICATION_KEY_PREFIX` is what makes the namespace a rule rather than a coincidence of
36
+ * string concatenation: a session id that already carries the prefix would otherwise collide back
37
+ * into the model's bucket. Product ids are `s_<hex>` so it cannot happen today, and
38
+ * `isReservedNotificationKey` lets a caller assert it instead of assuming it.
39
+ */
40
+ export declare const RESERVED_NOTIFICATION_KEY_PREFIX = "host:";
41
+ export declare function facetNotificationKey(sessionId: string): string;
42
+ /** True for a key in the facet's reserved namespace — i.e. one the session's own model never drains. */
43
+ export declare function isReservedNotificationKey(key: string): boolean;
@@ -0,0 +1,54 @@
1
+ import type { RuntimeObjectKind } from "./adapter.js";
2
+ export declare function isIdleSubscribeSenderAllowed(sender: {
3
+ isChild: boolean;
4
+ }): boolean;
5
+ export declare function isIdleSubscribeTargetAllowed(target: {
6
+ objectKind: RuntimeObjectKind;
7
+ hasReliableIdleSignal: boolean;
8
+ }): boolean;
9
+ export interface NotificationRecord {
10
+ notification_id: string;
11
+ origin: string;
12
+ queued_at: string;
13
+ content: string;
14
+ }
15
+ export interface NotificationQueue {
16
+ push(ownerKey: string, rec: {
17
+ origin: string;
18
+ content: string;
19
+ queuedAtMs: number;
20
+ }): void;
21
+ /**
22
+ * PHASE 7B: observe every push, WITHOUT consuming it. Returns an unsubscribe.
23
+ *
24
+ * The queue is the DURABLE record a host drains; this is the live signal a host can act on
25
+ * immediately. They are deliberately the same notice, correlated by `notification_id`: a listener
26
+ * that never fires (a crashed host, a host that reconnects later) loses nothing, because the entry
27
+ * is still queued for the drain -- which is what makes WS-15 §6.4's restart recovery possible at
28
+ * all. A listener must therefore NOT drain in response; the host acknowledges by draining.
29
+ *
30
+ * OPTIONAL, so a host that supplies its own `NotificationQueue` implementation still satisfies this
31
+ * interface. Its absence degrades to "drain only", never to a dropped notice.
32
+ */
33
+ subscribe?(listener: (ownerKey: string, rec: NotificationRecord) => void): () => void;
34
+ drain(ownerKey: string, max?: number): {
35
+ notifications: NotificationRecord[];
36
+ remaining: number;
37
+ };
38
+ pendingCount(ownerKey: string): number;
39
+ }
40
+ export declare function createNotificationQueue(): NotificationQueue;
41
+ export interface PendingIdleSubscription {
42
+ messageId: string;
43
+ subscriberKey: string;
44
+ targetKey: string;
45
+ createdAt: number;
46
+ expiresAt: number;
47
+ }
48
+ export interface IdleSubscriptionStore {
49
+ subscribe(sub: Omit<PendingIdleSubscription, "createdAt" | "expiresAt">, now: number): void;
50
+ fireIdle(targetKey: string, now: number, computeReducedStatus: (subscriberKey: string) => boolean, queue: NotificationQueue, originLabel: string): number;
51
+ sweepExpired(now: number): void;
52
+ pendingCount(targetKey: string): number;
53
+ }
54
+ export declare function createIdleSubscriptionStore(): IdleSubscriptionStore;
@@ -0,0 +1,39 @@
1
+ import type { PermissionMode } from "../permissions/types.js";
2
+ export type PermissionClassLabel = "prompts" | "bypasses" | "unknown";
3
+ export type CrossSessionInbound = "accept" | "hold" | "refuse";
4
+ export declare function classifyPermissionMode(mode: PermissionMode, opts: {
5
+ bypassAvailable: boolean;
6
+ }): PermissionClassLabel;
7
+ export declare function mapFromModeToPermissionClass(fromMode: "bypass" | "prompting" | undefined): PermissionClassLabel;
8
+ export declare function defaultInboundResult(receiverClass: PermissionClassLabel, senderClass: PermissionClassLabel): "accept" | "hold";
9
+ export interface InboundDecisionParams {
10
+ authenticated: boolean;
11
+ explicitSetting?: CrossSessionInbound;
12
+ receiverClass: PermissionClassLabel;
13
+ senderClass: PermissionClassLabel;
14
+ }
15
+ export declare function resolveInboundDecision(params: InboundDecisionParams): CrossSessionInbound;
16
+ export interface HeldEntry {
17
+ messageId: string;
18
+ reason: string;
19
+ kind: "default" | "explicit";
20
+ heldAt: number;
21
+ expiresAt?: number;
22
+ }
23
+ export interface Mailbox {
24
+ hold(receiverKey: string, entry: HeldEntry): boolean;
25
+ accept(receiverKey: string): boolean;
26
+ releaseAccepted(receiverKey: string, n?: number): void;
27
+ heldCount(receiverKey: string): number;
28
+ acceptedCount(receiverKey: string): number;
29
+ listHeld(receiverKey: string): readonly HeldEntry[];
30
+ takeHeld(receiverKey: string, messageId: string): HeldEntry | undefined;
31
+ reevaluate(receiverKey: string, decide: (entry: HeldEntry) => CrossSessionInbound): Array<{
32
+ entry: HeldEntry;
33
+ next: CrossSessionInbound;
34
+ }>;
35
+ sweepExpired(receiverKey: string, now: number): HeldEntry[];
36
+ }
37
+ export declare function createMailbox(): Mailbox;
38
+ export declare function buildDefaultHoldEntry(messageId: string, reason: string, now: number): HeldEntry;
39
+ export declare function buildExplicitHoldEntry(messageId: string, reason: string, now: number): HeldEntry;
@@ -0,0 +1,15 @@
1
+ export { serializeRuntimeAddress, createFakeMessagingRouterSeam, } from "./adapter.js";
2
+ export type { RuntimeKind, RuntimeObjectKind, RuntimeAddress, ListedRuntimeObject, DeliveryOutcome, GlobalAgentMessage, RuntimeMessagingAdapter, MessagingRouterSeam, FakeMessagingRouterSeam, ChildLike, ChildLikeRecord, ChildLikeStatus, } from "./adapter.js";
3
+ export { REFERENCE_RUNTIME_KIND, validateToField, buildSessionAddress, buildChildAddress, parseRuntimeAddress, sameAddress, } from "./addressing.js";
4
+ export type { ToFieldValidation } from "./addressing.js";
5
+ export { MAX_GLOBAL_MESSAGE_SIZE, DEFAULT_MESSAGE_TTL_MS, MAX_HOP_COUNT, RAPID_REPEAT_WINDOW_MS, HELD_INBOX_CAP, ACCEPTED_QUEUE_CAP, DEFAULT_HOLD_EXPIRY_MS, NOTIFY_IDLE_EXPIRY_MS, messageExceedsMaxSize, hopCountExceeded, delivered, queued, resumedAndDelivered, held, subscribed, deliveryUncertain, refused, ambiguous, notFound, unavailable, createLoopGuard, } from "./outcomes.js";
6
+ export type { LoopGuard } from "./outcomes.js";
7
+ export { childToListedRuntimeObject, resolveTarget } from "./resolution.js";
8
+ export type { ResolutionInputs, ResolutionResult } from "./resolution.js";
9
+ export { classifyPermissionMode, mapFromModeToPermissionClass, defaultInboundResult, resolveInboundDecision, createMailbox, buildDefaultHoldEntry, buildExplicitHoldEntry, } from "./inbound.js";
10
+ export type { PermissionClassLabel, CrossSessionInbound, InboundDecisionParams, HeldEntry, Mailbox } from "./inbound.js";
11
+ export { isIdleSubscribeSenderAllowed, isIdleSubscribeTargetAllowed, createNotificationQueue, createIdleSubscriptionStore, } from "./idle.js";
12
+ export type { NotificationRecord, NotificationQueue, PendingIdleSubscription, IdleSubscriptionStore } from "./idle.js";
13
+ export { AGENT_MESSAGE_TAG, RESERVED_NOTIFICATION_KEY_PREFIX, escapeAttributionText, escapeAttributionAttribute, facetNotificationKey, isReservedNotificationKey } from "./attribution.js";
14
+ export { MAX_TRACKED_MESSAGE_IDS, rememberBounded, createMessagingRouterSeam, createSubscriberDirectory, callerAddress, sendMessage, listAgents, readNotifications, createMessagingRouter, } from "./router.js";
15
+ export type { MessagingRouterSeamWithRoster, SubscriberDirectory, MessagingRuntimeDeps, CallerContext, SessionCallerContext, SendMessageInput, NotifyOutcome, SendMessageResult, ListAgentsInput, MessagingRouter, } from "./router.js";
@@ -0,0 +1,118 @@
1
+ import {
2
+ serializeRuntimeAddress2,
3
+ createFakeMessagingRouterSeam2,
4
+ REFERENCE_RUNTIME_KIND2,
5
+ validateToField2,
6
+ buildSessionAddress2,
7
+ buildChildAddress2,
8
+ parseRuntimeAddress2,
9
+ sameAddress2,
10
+ MAX_GLOBAL_MESSAGE_SIZE2,
11
+ DEFAULT_MESSAGE_TTL_MS2,
12
+ MAX_HOP_COUNT2,
13
+ RAPID_REPEAT_WINDOW_MS2,
14
+ HELD_INBOX_CAP2,
15
+ ACCEPTED_QUEUE_CAP2,
16
+ DEFAULT_HOLD_EXPIRY_MS2,
17
+ NOTIFY_IDLE_EXPIRY_MS2,
18
+ messageExceedsMaxSize2,
19
+ hopCountExceeded2,
20
+ delivered2,
21
+ queued2,
22
+ resumedAndDelivered2,
23
+ held2,
24
+ subscribed2,
25
+ deliveryUncertain2,
26
+ refused2,
27
+ ambiguous2,
28
+ notFound2,
29
+ unavailable2,
30
+ createLoopGuard2,
31
+ childToListedRuntimeObject2,
32
+ resolveTarget2,
33
+ classifyPermissionMode2,
34
+ mapFromModeToPermissionClass2,
35
+ defaultInboundResult2,
36
+ resolveInboundDecision2,
37
+ createMailbox2,
38
+ buildDefaultHoldEntry2,
39
+ buildExplicitHoldEntry2,
40
+ isIdleSubscribeSenderAllowed2,
41
+ isIdleSubscribeTargetAllowed2,
42
+ createNotificationQueue2,
43
+ createIdleSubscriptionStore2,
44
+ AGENT_MESSAGE_TAG2,
45
+ escapeAttributionText2,
46
+ escapeAttributionAttribute2,
47
+ RESERVED_NOTIFICATION_KEY_PREFIX2,
48
+ facetNotificationKey2,
49
+ isReservedNotificationKey2,
50
+ MAX_TRACKED_MESSAGE_IDS2,
51
+ rememberBounded2,
52
+ createMessagingRouterSeam2,
53
+ createSubscriberDirectory2,
54
+ callerAddress2,
55
+ sendMessage2,
56
+ listAgents2,
57
+ readNotifications2,
58
+ createMessagingRouter2
59
+ } from "../index-h1tryj38.js";
60
+ export {
61
+ ACCEPTED_QUEUE_CAP2 as ACCEPTED_QUEUE_CAP,
62
+ AGENT_MESSAGE_TAG2 as AGENT_MESSAGE_TAG,
63
+ DEFAULT_HOLD_EXPIRY_MS2 as DEFAULT_HOLD_EXPIRY_MS,
64
+ DEFAULT_MESSAGE_TTL_MS2 as DEFAULT_MESSAGE_TTL_MS,
65
+ HELD_INBOX_CAP2 as HELD_INBOX_CAP,
66
+ MAX_GLOBAL_MESSAGE_SIZE2 as MAX_GLOBAL_MESSAGE_SIZE,
67
+ MAX_HOP_COUNT2 as MAX_HOP_COUNT,
68
+ MAX_TRACKED_MESSAGE_IDS2 as MAX_TRACKED_MESSAGE_IDS,
69
+ NOTIFY_IDLE_EXPIRY_MS2 as NOTIFY_IDLE_EXPIRY_MS,
70
+ RAPID_REPEAT_WINDOW_MS2 as RAPID_REPEAT_WINDOW_MS,
71
+ REFERENCE_RUNTIME_KIND2 as REFERENCE_RUNTIME_KIND,
72
+ RESERVED_NOTIFICATION_KEY_PREFIX2 as RESERVED_NOTIFICATION_KEY_PREFIX,
73
+ ambiguous2 as ambiguous,
74
+ buildChildAddress2 as buildChildAddress,
75
+ buildDefaultHoldEntry2 as buildDefaultHoldEntry,
76
+ buildExplicitHoldEntry2 as buildExplicitHoldEntry,
77
+ buildSessionAddress2 as buildSessionAddress,
78
+ callerAddress2 as callerAddress,
79
+ childToListedRuntimeObject2 as childToListedRuntimeObject,
80
+ classifyPermissionMode2 as classifyPermissionMode,
81
+ createFakeMessagingRouterSeam2 as createFakeMessagingRouterSeam,
82
+ createIdleSubscriptionStore2 as createIdleSubscriptionStore,
83
+ createLoopGuard2 as createLoopGuard,
84
+ createMailbox2 as createMailbox,
85
+ createMessagingRouter2 as createMessagingRouter,
86
+ createMessagingRouterSeam2 as createMessagingRouterSeam,
87
+ createNotificationQueue2 as createNotificationQueue,
88
+ createSubscriberDirectory2 as createSubscriberDirectory,
89
+ defaultInboundResult2 as defaultInboundResult,
90
+ delivered2 as delivered,
91
+ deliveryUncertain2 as deliveryUncertain,
92
+ escapeAttributionAttribute2 as escapeAttributionAttribute,
93
+ escapeAttributionText2 as escapeAttributionText,
94
+ facetNotificationKey2 as facetNotificationKey,
95
+ held2 as held,
96
+ hopCountExceeded2 as hopCountExceeded,
97
+ isIdleSubscribeSenderAllowed2 as isIdleSubscribeSenderAllowed,
98
+ isIdleSubscribeTargetAllowed2 as isIdleSubscribeTargetAllowed,
99
+ isReservedNotificationKey2 as isReservedNotificationKey,
100
+ listAgents2 as listAgents,
101
+ mapFromModeToPermissionClass2 as mapFromModeToPermissionClass,
102
+ messageExceedsMaxSize2 as messageExceedsMaxSize,
103
+ notFound2 as notFound,
104
+ parseRuntimeAddress2 as parseRuntimeAddress,
105
+ queued2 as queued,
106
+ readNotifications2 as readNotifications,
107
+ refused2 as refused,
108
+ rememberBounded2 as rememberBounded,
109
+ resolveInboundDecision2 as resolveInboundDecision,
110
+ resolveTarget2 as resolveTarget,
111
+ resumedAndDelivered2 as resumedAndDelivered,
112
+ sameAddress2 as sameAddress,
113
+ sendMessage2 as sendMessage,
114
+ serializeRuntimeAddress2 as serializeRuntimeAddress,
115
+ subscribed2 as subscribed,
116
+ unavailable2 as unavailable,
117
+ validateToField2 as validateToField
118
+ };