@sw4rm/js-sdk 0.5.0 → 0.6.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.
@@ -0,0 +1,41 @@
1
+ import { ErrorCode } from '../internal/errorMapping.js';
2
+ export declare const MIN_GRACE_PERIOD_MS = 5000;
3
+ export type CancellationMetadataValue = string | number | boolean | null;
4
+ export type CancellationMetadata = Record<string, CancellationMetadataValue>;
5
+ export interface CancelDelegationRequest {
6
+ correlationId: string;
7
+ reason?: string;
8
+ gracePeriodMs?: number;
9
+ metadata?: Record<string, unknown>;
10
+ }
11
+ export interface CancelDelegationResponse {
12
+ acknowledged: boolean;
13
+ correlationId: string;
14
+ gracePeriodMs: number;
15
+ message: string;
16
+ metadata: CancellationMetadata;
17
+ }
18
+ export interface CancellationFlag {
19
+ cancelled: boolean;
20
+ gracePeriodMs: number;
21
+ cancelTimeMs: number;
22
+ metadata: CancellationMetadata;
23
+ }
24
+ export interface CancellationManagerOptions {
25
+ nowMsFn?: () => number;
26
+ }
27
+ export declare class CancellationValidationError extends Error {
28
+ constructor(message: string);
29
+ }
30
+ export declare class CancellationManager {
31
+ readonly childDelegations: Map<string, Set<string>>;
32
+ readonly cancellationFlags: Map<string, CancellationFlag>;
33
+ private readonly nowMs;
34
+ constructor(options?: CancellationManagerOptions);
35
+ registerChildDelegation(parentCorrelationId: string, childCorrelationId: string): void;
36
+ handleCancelDelegation(cancel: CancelDelegationRequest): CancelDelegationResponse;
37
+ isCancelled(correlationId: string): boolean;
38
+ isGraceExpired(correlationId: string, nowMs?: number): boolean;
39
+ forcedPreemptionErrorCode(correlationId: string, nowMs?: number): ErrorCode;
40
+ collectForcedPreemptions(correlationIds: Iterable<string>, nowMs?: number): Set<string>;
41
+ }
@@ -0,0 +1,20 @@
1
+ import { type BudgetEnvelope, type HandoffRequest, type HandoffResponse, type SwarmDelegationPolicy } from '../clients/handoff.js';
2
+ export declare const RETRY_AFTER_JITTER_RATIO = 0.2;
3
+ export declare const DEFAULT_EFFECTIVE_MAX_REDIRECTS = 2;
4
+ export interface DelegateToSwarmOptions {
5
+ sendHandoffFn: (request: HandoffRequest) => Promise<HandoffResponse> | HandoffResponse;
6
+ fromAgent: string;
7
+ toAgent: string;
8
+ reason: string;
9
+ budget: BudgetEnvelope;
10
+ delegationPolicy?: SwarmDelegationPolicy;
11
+ requestId?: string;
12
+ contextSnapshot?: Uint8Array;
13
+ capabilitiesRequired?: string[];
14
+ priority?: number;
15
+ timeoutMs?: number;
16
+ nowMsFn?: () => number;
17
+ sleepMsFn?: (milliseconds: number) => Promise<void> | void;
18
+ randUniformFn?: (low: number, high: number) => number;
19
+ }
20
+ export declare function delegateToSwarm(options: DelegateToSwarmOptions): Promise<HandoffResponse>;
@@ -0,0 +1,80 @@
1
+ import type { HandoffRequest, HandoffResponse } from '../clients/handoff.js';
2
+ export declare const REGISTRATION_TYPE_STANDARD_AGENT = 1;
3
+ export declare const REGISTRATION_TYPE_SWARM_GATEWAY = 2;
4
+ export declare const AGENT_STATE_INITIALIZING = 1;
5
+ export declare const AGENT_STATE_RUNNING = 4;
6
+ export declare const AGENT_STATE_FAILED = 10;
7
+ export declare const AGENT_STATE_SHUTTING_DOWN = 11;
8
+ export declare const DEFAULT_PEER_LIVENESS_THRESHOLD_MS = 30000;
9
+ export declare const NON_SERVING_AGENT_STATES: Set<number>;
10
+ export interface GatewayPeerDescriptor {
11
+ agentId: string;
12
+ registrationType: number;
13
+ capabilities: string[];
14
+ }
15
+ export interface PeerRuntimeState {
16
+ state: number;
17
+ lastHeartbeatMs: number;
18
+ cooldownUntilMs: number;
19
+ }
20
+ export interface PeerSelectorOptions {
21
+ localAgentId: string;
22
+ localCapabilities: string[];
23
+ nowMsFn?: () => number;
24
+ peerHealthFn?: (peer: GatewayPeerDescriptor) => boolean;
25
+ livenessThresholdMs?: number;
26
+ }
27
+ export interface UpdatePeerRuntimeStateOptions {
28
+ state?: number;
29
+ lastHeartbeatMs?: number;
30
+ cooldownUntilMs?: number;
31
+ }
32
+ export interface RecordPeerOverloadedOptions {
33
+ retryAfterMs?: number;
34
+ localCooldownMs?: number;
35
+ }
36
+ export interface GatewayRedirectEmitterOptions {
37
+ agentId: string;
38
+ capabilities?: string[];
39
+ retryAfterMs?: number;
40
+ peerDescriptors?: GatewayPeerDescriptor[];
41
+ peerHealthFn?: (peer: GatewayPeerDescriptor) => boolean;
42
+ nowMsFn?: () => number;
43
+ peerLivenessThresholdMs?: number;
44
+ }
45
+ export declare class GatewayValidationError extends Error {
46
+ constructor(message: string);
47
+ }
48
+ export declare class PeerSelector {
49
+ private readonly localAgentId;
50
+ private readonly localCapabilities;
51
+ private readonly nowMs;
52
+ private readonly peerHealthFn;
53
+ private readonly livenessThresholdMs;
54
+ private peers;
55
+ private runtime;
56
+ private rrCursor;
57
+ constructor(options: PeerSelectorOptions);
58
+ setPeers(peers: GatewayPeerDescriptor[]): void;
59
+ updatePeerRuntimeState(agentId: string, options?: UpdatePeerRuntimeStateOptions): void;
60
+ touchPeerHeartbeat(agentId: string, options?: Pick<UpdatePeerRuntimeStateOptions, 'state'> & {
61
+ nowMs?: number;
62
+ }): void;
63
+ recordPeerOverloaded(agentId: string, options?: RecordPeerOverloadedOptions): void;
64
+ isEligible(peer: GatewayPeerDescriptor): boolean;
65
+ selectPeer(): string;
66
+ private ensureRuntime;
67
+ private isHealthy;
68
+ }
69
+ export declare class GatewayRedirectEmitter {
70
+ private readonly retryAfterMs;
71
+ private readonly peerSelector;
72
+ constructor(options: GatewayRedirectEmitterOptions);
73
+ setPeerDescriptors(peers: GatewayPeerDescriptor[]): void;
74
+ updatePeerRuntimeState(agentId: string, options?: UpdatePeerRuntimeStateOptions): void;
75
+ touchPeerHeartbeat(agentId: string, options?: Pick<UpdatePeerRuntimeStateOptions, 'state'> & {
76
+ nowMs?: number;
77
+ }): void;
78
+ recordPeerOverloaded(agentId: string, options?: RecordPeerOverloadedOptions): void;
79
+ emitOverloadedResponse(request: HandoffRequest): HandoffResponse;
80
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sw4rm/js-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "SW4RM Agentic Protocol JavaScript/TypeScript SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.cjs",
@@ -47,6 +47,10 @@ enum ErrorCode {
47
47
  TTL_EXPIRED = 13;
48
48
  DUPLICATE_DETECTED = 14;
49
49
  ALREADY_IN_PROGRESS = 15;
50
+ // SW4-004 Inter-Swarm Composition (values 16-19)
51
+ OVERLOADED = 16;
52
+ // SW4-005 Spillover Routing (values 20-23)
53
+ REDIRECT = 20;
50
54
  INTERNAL_ERROR = 99;
51
55
  }
52
56
 
@@ -122,6 +126,9 @@ message Envelope {
122
126
  google.protobuf.Timestamp timestamp = 14;
123
127
  bytes payload = 15; // serialized content per content_type
124
128
  EnvelopeState state = 16; // lifecycle state of the envelope
129
+
130
+ // SW4-004 Inter-Swarm Composition (fields 100-109)
131
+ string parent_correlation_id = 100; // set on first envelope crossing a swarm boundary
125
132
  }
126
133
 
127
134
  message Ack {
@@ -18,6 +18,35 @@ enum HandoffStatus {
18
18
  EXPIRED = 5;
19
19
  }
20
20
 
21
+ // SW4-004 Inter-Swarm Composition
22
+ message BudgetEnvelope {
23
+ uint64 token_budget_remaining = 1; // combined LLM input+output tokens
24
+ uint64 wall_time_remaining_ms = 2;
25
+ uint64 deadline_epoch_ms = 3;
26
+ uint32 current_depth = 4;
27
+ uint32 max_delegation_depth = 5;
28
+ }
29
+
30
+ message SwarmDelegationPolicy {
31
+ uint32 max_retries_on_overloaded = 1;
32
+ uint64 initial_backoff_ms = 2;
33
+ double backoff_multiplier = 3;
34
+ uint64 max_backoff_ms = 4;
35
+ bool allow_spillover_routing = 5; // permits redirect to equivalent peer gateway
36
+ uint32 max_redirects = 6; // SW4-005 redirect chain limit
37
+ }
38
+
39
+ message CancelDelegation {
40
+ string correlation_id = 1; // identifies the delegation to cancel
41
+ string reason = 2; // human-readable cancellation reason
42
+ uint64 grace_period_ms = 3; // time for cleanup before forced termination (min 5000ms)
43
+ }
44
+
45
+ message CancelDelegationResponse {
46
+ bool acknowledged = 1;
47
+ string message = 2;
48
+ }
49
+
21
50
  message HandoffRequest {
22
51
  string request_id = 1;
23
52
  string from_agent = 2;
@@ -27,6 +56,10 @@ message HandoffRequest {
27
56
  repeated string capabilities_required = 6;
28
57
  int32 priority = 7;
29
58
  google.protobuf.Duration timeout = 8;
59
+
60
+ // SW4-004 Inter-Swarm Composition (fields 100-109)
61
+ BudgetEnvelope budget = 100;
62
+ SwarmDelegationPolicy delegation_policy = 101;
30
63
  }
31
64
 
32
65
  message HandoffResponse {
@@ -34,6 +67,13 @@ message HandoffResponse {
34
67
  bool accepted = 2;
35
68
  string accepting_agent = 3;
36
69
  string rejection_reason = 4;
70
+
71
+ // SW4-004 Inter-Swarm Composition (fields 100-109)
72
+ sw4rm.common.ErrorCode rejection_code = 100;
73
+ uint64 retry_after_ms = 101;
74
+
75
+ // SW4-005 Spillover Routing (fields 110-119)
76
+ string redirect_to_agent_id = 110;
37
77
  }
38
78
 
39
79
  message GetPendingHandoffsRequest {
@@ -60,4 +100,6 @@ service HandoffService {
60
100
  rpc RejectHandoff(HandoffResponse) returns (sw4rm.common.Empty);
61
101
  rpc GetPendingHandoffs(GetPendingHandoffsRequest) returns (GetPendingHandoffsResponse);
62
102
  rpc CompleteHandoff(CompleteHandoffRequest) returns (CompleteHandoffResponse);
103
+ // SW4-004 Inter-Swarm Composition: cascading cancellation
104
+ rpc CancelDelegation(sw4rm.handoff.CancelDelegation) returns (CancelDelegationResponse);
63
105
  }
@@ -5,6 +5,13 @@ package sw4rm.registry;
5
5
  import "google/protobuf/timestamp.proto";
6
6
  import "common.proto";
7
7
 
8
+ // SW4-004 Inter-Swarm Composition
9
+ enum RegistrationType {
10
+ REGISTRATION_TYPE_UNSPECIFIED = 0;
11
+ STANDARD_AGENT = 1;
12
+ SWARM_GATEWAY = 2;
13
+ }
14
+
8
15
  message AgentDescriptor {
9
16
  string agent_id = 1;
10
17
  string name = 2;
@@ -14,6 +21,10 @@ message AgentDescriptor {
14
21
  repeated string modalities_supported = 6; // MIME types
15
22
  repeated string reasoning_connectors = 7; // URIs
16
23
  bytes public_key = 8; // optional
24
+
25
+ // SW4-004 Inter-Swarm Composition (fields 100-109)
26
+ RegistrationType registration_type = 100; // default STANDARD_AGENT
27
+ uint32 max_concurrent_delegations = 101; // normative for SWARM_GATEWAY, advisory for STANDARD_AGENT
17
28
  }
18
29
 
19
30
  message RegisterAgentRequest { AgentDescriptor agent = 1; }