@sw4rm/js-sdk 0.3.0 → 0.5.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/README.md +13 -0
- package/dist/cjs/index.cjs +3576 -342
- package/dist/esm/index.js +3497 -336
- package/dist/types/agentConfig.d.ts +245 -0
- package/dist/types/audit.d.ts +214 -0
- package/dist/types/clients/handoff.d.ts +188 -0
- package/dist/types/clients/negotiationRoom.d.ts +423 -0
- package/dist/types/clients/negotiationRoomStore.d.ts +155 -0
- package/dist/types/clients/workflow.d.ts +316 -0
- package/dist/types/constants/index.d.ts +100 -0
- package/dist/types/index.d.ts +15 -4
- package/dist/types/internal/baseClient.d.ts +7 -1
- package/dist/types/internal/envelope.d.ts +16 -0
- package/dist/types/internal/errorMapping.d.ts +114 -0
- package/dist/types/internal/worktreeState.d.ts +60 -0
- package/dist/types/persistentActivityBuffer.d.ts +94 -0
- package/dist/types/runtime/agentState.d.ts +205 -0
- package/dist/types/runtime/policyStore.d.ts +391 -0
- package/dist/types/runtime/voting.d.ts +208 -0
- package/package.json +4 -2
- package/protos/activity.proto +24 -0
- package/protos/common.proto +134 -0
- package/protos/connector.proto +29 -0
- package/protos/handoff.proto +63 -0
- package/protos/hitl.proto +23 -0
- package/protos/logging.proto +20 -0
- package/protos/negotiation.proto +57 -0
- package/protos/negotiation_room.proto +220 -0
- package/protos/policy.proto +55 -0
- package/protos/reasoning.proto +41 -0
- package/protos/registry.proto +36 -0
- package/protos/router.proto +16 -0
- package/protos/scheduler.proto +52 -0
- package/protos/scheduler_policy.proto +36 -0
- package/protos/tool.proto +47 -0
- package/protos/workflow.proto +116 -0
- package/protos/worktree.proto +33 -0
|
@@ -1,14 +1,74 @@
|
|
|
1
1
|
export type WorktreeState = 'UNBOUND' | 'BOUND_HOME' | 'SWITCH_PENDING' | 'BOUND_NON_HOME' | 'BIND_FAILED';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a worktree state transition is valid.
|
|
4
|
+
*/
|
|
5
|
+
export declare function isValidWorktreeTransition(from: WorktreeState, to: WorktreeState): boolean;
|
|
6
|
+
export declare class WorktreeTransitionError extends Error {
|
|
7
|
+
readonly fromState: WorktreeState;
|
|
8
|
+
readonly toState: WorktreeState;
|
|
9
|
+
constructor(from: WorktreeState, to: WorktreeState);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Persistent worktree state machine with full spec §16 support.
|
|
13
|
+
*
|
|
14
|
+
* Supports SWITCH_PENDING approval flow with TTL on BOUND_NON_HOME.
|
|
15
|
+
*/
|
|
2
16
|
export declare class PersistentWorktreeState {
|
|
3
17
|
private state;
|
|
4
18
|
private repoId?;
|
|
5
19
|
private worktreeId?;
|
|
20
|
+
private homeRepoId?;
|
|
21
|
+
private homeWorktreeId?;
|
|
22
|
+
private switchTtlMs?;
|
|
23
|
+
private switchTimer?;
|
|
24
|
+
/**
|
|
25
|
+
* Transition to a new state with validation.
|
|
26
|
+
* @throws WorktreeTransitionError if transition is invalid
|
|
27
|
+
*/
|
|
28
|
+
private transitionTo;
|
|
29
|
+
/**
|
|
30
|
+
* Bind to a home worktree (UNBOUND -> BOUND_HOME or BIND_FAILED -> BOUND_HOME).
|
|
31
|
+
*/
|
|
6
32
|
bind(repoId: string, worktreeId: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Handle bind failure (UNBOUND -> BIND_FAILED).
|
|
35
|
+
*/
|
|
36
|
+
bindFailed(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Unbind from current worktree.
|
|
39
|
+
*/
|
|
7
40
|
unbind(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Request switch to a non-home worktree (BOUND_HOME -> SWITCH_PENDING).
|
|
43
|
+
* Requires approval or rejection before taking effect.
|
|
44
|
+
*/
|
|
45
|
+
requestSwitch(targetRepoId: string, targetWorktreeId: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Approve a pending switch (SWITCH_PENDING -> BOUND_NON_HOME).
|
|
48
|
+
* @param ttlMs - Time-to-live in milliseconds before auto-reverting to BOUND_HOME
|
|
49
|
+
*/
|
|
50
|
+
approveSwitch(ttlMs?: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* Reject a pending switch (SWITCH_PENDING -> BOUND_HOME).
|
|
53
|
+
*/
|
|
54
|
+
rejectSwitch(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Revert from non-home to home worktree (BOUND_NON_HOME -> BOUND_HOME).
|
|
57
|
+
* Called on TTL expiry or explicit revoke.
|
|
58
|
+
*/
|
|
59
|
+
revertToHome(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Reset from BIND_FAILED to UNBOUND for retry.
|
|
62
|
+
*/
|
|
63
|
+
resetFromFailed(): void;
|
|
64
|
+
private clearSwitchTimer;
|
|
8
65
|
setState(state: WorktreeState): void;
|
|
9
66
|
current(): {
|
|
10
67
|
state: WorktreeState;
|
|
11
68
|
repo_id: string | undefined;
|
|
12
69
|
worktree_id: string | undefined;
|
|
70
|
+
home_repo_id: string | undefined;
|
|
71
|
+
home_worktree_id: string | undefined;
|
|
72
|
+
switch_ttl_ms: number | undefined;
|
|
13
73
|
};
|
|
14
74
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { EnvelopeState } from './constants/index.js';
|
|
2
|
+
export interface EnvelopeRecord {
|
|
3
|
+
message_id: string;
|
|
4
|
+
direction: 'in' | 'out';
|
|
5
|
+
envelope: Record<string, unknown>;
|
|
6
|
+
ts_ms: number;
|
|
7
|
+
ack_stage: number;
|
|
8
|
+
error_code: number;
|
|
9
|
+
ack_note: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PersistenceBackend {
|
|
12
|
+
load(): {
|
|
13
|
+
records: Record<string, EnvelopeRecord>;
|
|
14
|
+
order: string[];
|
|
15
|
+
};
|
|
16
|
+
save(records: Record<string, EnvelopeRecord>, order: string[]): void;
|
|
17
|
+
clear(): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* JSON file persistence backend.
|
|
21
|
+
*/
|
|
22
|
+
export declare class JSONFilePersistence implements PersistenceBackend {
|
|
23
|
+
private filePath;
|
|
24
|
+
constructor(filePath?: string);
|
|
25
|
+
load(): {
|
|
26
|
+
records: Record<string, EnvelopeRecord>;
|
|
27
|
+
order: string[];
|
|
28
|
+
};
|
|
29
|
+
save(records: Record<string, EnvelopeRecord>, order: string[]): void;
|
|
30
|
+
clear(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Persistent Activity Buffer with Three-ID model support.
|
|
34
|
+
*
|
|
35
|
+
* Tracks inbound/outbound envelopes by message_id and records ACK progression.
|
|
36
|
+
* Supports multiple persistence backends (JSON file, etc.) and provides
|
|
37
|
+
* reconciliation on startup to restore previous state.
|
|
38
|
+
*
|
|
39
|
+
* When the buffer is full, new records are REJECTED with BufferFullError
|
|
40
|
+
* per spec compliance (not silently pruned).
|
|
41
|
+
*/
|
|
42
|
+
export declare class PersistentActivityBuffer {
|
|
43
|
+
private byId;
|
|
44
|
+
private byIdempotencyToken;
|
|
45
|
+
private order;
|
|
46
|
+
private maxItems;
|
|
47
|
+
private persistence;
|
|
48
|
+
private dedupWindowS;
|
|
49
|
+
private dirty;
|
|
50
|
+
constructor(opts?: {
|
|
51
|
+
maxItems?: number;
|
|
52
|
+
persistence?: PersistenceBackend;
|
|
53
|
+
dedupWindowS?: number;
|
|
54
|
+
});
|
|
55
|
+
private loadFromPersistence;
|
|
56
|
+
private saveToPersistence;
|
|
57
|
+
private checkCapacity;
|
|
58
|
+
private cleanupExpiredDedupEntries;
|
|
59
|
+
/**
|
|
60
|
+
* Record an incoming envelope. Throws BufferFullError if buffer is at capacity.
|
|
61
|
+
*/
|
|
62
|
+
recordIncoming(envelope: Record<string, unknown>): EnvelopeRecord;
|
|
63
|
+
/**
|
|
64
|
+
* Record an outgoing envelope. Throws BufferFullError if buffer is at capacity.
|
|
65
|
+
*/
|
|
66
|
+
recordOutgoing(envelope: Record<string, unknown>): EnvelopeRecord;
|
|
67
|
+
/**
|
|
68
|
+
* Process an ACK for a previously recorded message.
|
|
69
|
+
*/
|
|
70
|
+
ack(ackMsg: {
|
|
71
|
+
ack_for_message_id: string;
|
|
72
|
+
ack_stage?: number;
|
|
73
|
+
error_code?: number;
|
|
74
|
+
note?: string;
|
|
75
|
+
}): EnvelopeRecord | undefined;
|
|
76
|
+
/** Get record by message ID. */
|
|
77
|
+
get(messageId: string): EnvelopeRecord | undefined;
|
|
78
|
+
/** Get record by idempotency token (for deduplication). */
|
|
79
|
+
getByIdempotencyToken(token: string): EnvelopeRecord | undefined;
|
|
80
|
+
/** Get all un-ACKed records. */
|
|
81
|
+
unacked(): EnvelopeRecord[];
|
|
82
|
+
/** Get N most recent records. */
|
|
83
|
+
recent(n?: number): EnvelopeRecord[];
|
|
84
|
+
/** Update envelope state for a message. */
|
|
85
|
+
updateState(messageId: string, newState: EnvelopeState): EnvelopeRecord | undefined;
|
|
86
|
+
/** Return unacked outgoing messages for reconciliation. */
|
|
87
|
+
reconcile(): EnvelopeRecord[];
|
|
88
|
+
/** Force save to persistence. */
|
|
89
|
+
flush(): void;
|
|
90
|
+
/** Clear all records. */
|
|
91
|
+
clear(): void;
|
|
92
|
+
/** Get the count of records. */
|
|
93
|
+
get size(): number;
|
|
94
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent runtime state machine for SW4RM.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the AgentState enum and state transition validation
|
|
5
|
+
* for implementing the agent lifecycle as specified in spec section 8.
|
|
6
|
+
*
|
|
7
|
+
* The agent lifecycle states are:
|
|
8
|
+
* - INITIALIZING: Agent starting up and registering
|
|
9
|
+
* - RUNNABLE: Agent ready to accept tasks
|
|
10
|
+
* - SCHEDULED: Agent has task assigned but not yet running
|
|
11
|
+
* - RUNNING: Agent actively executing task
|
|
12
|
+
* - WAITING: Agent waiting for external input
|
|
13
|
+
* - WAITING_RESOURCES: Agent waiting for resources
|
|
14
|
+
* - SUSPENDED: Agent paused by scheduler
|
|
15
|
+
* - RESUMED: Agent transitioning from suspended to running
|
|
16
|
+
* - COMPLETED: Agent finished current task
|
|
17
|
+
* - FAILED: Agent encountered error
|
|
18
|
+
* - SHUTTING_DOWN: Agent gracefully terminating
|
|
19
|
+
* - RECOVERING: Agent recovering from failure
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Agent lifecycle states as defined in spec section 8.
|
|
23
|
+
*/
|
|
24
|
+
export declare enum AgentState {
|
|
25
|
+
/** Agent state not set */
|
|
26
|
+
AGENT_STATE_UNSPECIFIED = 0,
|
|
27
|
+
/** Agent starting up and registering */
|
|
28
|
+
INITIALIZING = 1,
|
|
29
|
+
/** Agent ready to accept tasks */
|
|
30
|
+
RUNNABLE = 2,
|
|
31
|
+
/** Agent has task assigned but not yet running */
|
|
32
|
+
SCHEDULED = 3,
|
|
33
|
+
/** Agent actively executing task */
|
|
34
|
+
RUNNING = 4,
|
|
35
|
+
/** Agent waiting for external input */
|
|
36
|
+
WAITING = 5,
|
|
37
|
+
/** Agent waiting for resources */
|
|
38
|
+
WAITING_RESOURCES = 6,
|
|
39
|
+
/** Agent paused by scheduler */
|
|
40
|
+
SUSPENDED = 7,
|
|
41
|
+
/** Agent transitioning from suspended to running */
|
|
42
|
+
RESUMED = 8,
|
|
43
|
+
/** Agent finished current task */
|
|
44
|
+
COMPLETED = 9,
|
|
45
|
+
/** Agent encountered error */
|
|
46
|
+
FAILED = 10,
|
|
47
|
+
/** Agent gracefully terminating */
|
|
48
|
+
SHUTTING_DOWN = 11,
|
|
49
|
+
/** Agent recovering from failure */
|
|
50
|
+
RECOVERING = 12
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when an invalid state transition is attempted.
|
|
54
|
+
*/
|
|
55
|
+
export declare class StateTransitionError extends Error {
|
|
56
|
+
readonly fromState: AgentState;
|
|
57
|
+
readonly toState: AgentState;
|
|
58
|
+
constructor(fromState: AgentState, toState: AgentState);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if a state transition is valid.
|
|
62
|
+
*
|
|
63
|
+
* @param fromState - The current state
|
|
64
|
+
* @param toState - The target state
|
|
65
|
+
* @returns True if the transition is valid, false otherwise
|
|
66
|
+
*/
|
|
67
|
+
export declare function isValidTransition(fromState: AgentState, toState: AgentState): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Get all valid target states from a given state.
|
|
70
|
+
*
|
|
71
|
+
* @param fromState - The current state
|
|
72
|
+
* @returns Array of valid target states
|
|
73
|
+
*/
|
|
74
|
+
export declare function getValidTransitions(fromState: AgentState): AgentState[];
|
|
75
|
+
/**
|
|
76
|
+
* Lifecycle hook types for agent state changes.
|
|
77
|
+
*/
|
|
78
|
+
export interface AgentLifecycleHooks {
|
|
79
|
+
/** Called on any state change */
|
|
80
|
+
onStateChange?: (fromState: AgentState, toState: AgentState, context?: Record<string, unknown>) => void | Promise<void>;
|
|
81
|
+
/** Called when agent becomes SCHEDULED */
|
|
82
|
+
onScheduled?: (taskId: string, context?: Record<string, unknown>) => void | Promise<void>;
|
|
83
|
+
/** Called when agent is preempted (RUNNING -> SUSPENDED) */
|
|
84
|
+
onPreempt?: (reason: string, context?: Record<string, unknown>) => void | Promise<void>;
|
|
85
|
+
/** Called when agent resumes (RESUMED -> RUNNING) */
|
|
86
|
+
onResume?: (context?: Record<string, unknown>) => void | Promise<void>;
|
|
87
|
+
/** Called when agent starts waiting (RUNNING -> WAITING) */
|
|
88
|
+
onWait?: (reason: string, context?: Record<string, unknown>) => void | Promise<void>;
|
|
89
|
+
/** Called when agent waits for resources (RUNNING -> WAITING_RESOURCES) */
|
|
90
|
+
onWaitResources?: (resources: string[], context?: Record<string, unknown>) => void | Promise<void>;
|
|
91
|
+
/** Called when task completes (RUNNING -> COMPLETED) */
|
|
92
|
+
onComplete?: (result?: unknown, context?: Record<string, unknown>) => void | Promise<void>;
|
|
93
|
+
/** Called when agent fails (any -> FAILED) */
|
|
94
|
+
onFail?: (error: Error, context?: Record<string, unknown>) => void | Promise<void>;
|
|
95
|
+
/** Called when shutdown starts (RUNNING -> SHUTTING_DOWN) */
|
|
96
|
+
onShutdown?: (gracePeriodMs: number, context?: Record<string, unknown>) => void | Promise<void>;
|
|
97
|
+
/** Called when recovery starts (FAILED -> RECOVERING) */
|
|
98
|
+
onRecover?: (context?: Record<string, unknown>) => void | Promise<void>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Agent state machine implementation.
|
|
102
|
+
*
|
|
103
|
+
* Manages agent lifecycle state transitions with validation and lifecycle hooks.
|
|
104
|
+
*/
|
|
105
|
+
export declare class AgentStateMachine {
|
|
106
|
+
private state;
|
|
107
|
+
private hooks;
|
|
108
|
+
private stateHistory;
|
|
109
|
+
/**
|
|
110
|
+
* Create a new agent state machine.
|
|
111
|
+
*
|
|
112
|
+
* @param hooks - Optional lifecycle hooks
|
|
113
|
+
*/
|
|
114
|
+
constructor(hooks?: AgentLifecycleHooks);
|
|
115
|
+
/**
|
|
116
|
+
* Get the current state.
|
|
117
|
+
*
|
|
118
|
+
* @returns The current agent state
|
|
119
|
+
*/
|
|
120
|
+
getState(): AgentState;
|
|
121
|
+
/**
|
|
122
|
+
* Get the state history.
|
|
123
|
+
*
|
|
124
|
+
* @returns Array of state transitions with timestamps
|
|
125
|
+
*/
|
|
126
|
+
getStateHistory(): Array<{
|
|
127
|
+
state: AgentState;
|
|
128
|
+
timestamp: string;
|
|
129
|
+
context?: Record<string, unknown>;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Initialize the agent (transition to INITIALIZING).
|
|
133
|
+
*
|
|
134
|
+
* @throws StateTransitionError if already initialized
|
|
135
|
+
*/
|
|
136
|
+
initialize(): Promise<void>;
|
|
137
|
+
/**
|
|
138
|
+
* Transition to a new state.
|
|
139
|
+
*
|
|
140
|
+
* @param toState - The target state
|
|
141
|
+
* @param context - Optional context for the transition
|
|
142
|
+
* @throws StateTransitionError if the transition is invalid
|
|
143
|
+
*/
|
|
144
|
+
transitionTo(toState: AgentState, context?: Record<string, unknown>): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* Perform the state transition and call hooks.
|
|
147
|
+
*/
|
|
148
|
+
private doTransition;
|
|
149
|
+
/**
|
|
150
|
+
* Call specific lifecycle hooks based on the transition.
|
|
151
|
+
*/
|
|
152
|
+
private callSpecificHooks;
|
|
153
|
+
/**
|
|
154
|
+
* Check if the agent can transition to a given state.
|
|
155
|
+
*
|
|
156
|
+
* @param toState - The target state
|
|
157
|
+
* @returns True if the transition is valid
|
|
158
|
+
*/
|
|
159
|
+
canTransitionTo(toState: AgentState): boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Get all states the agent can currently transition to.
|
|
162
|
+
*
|
|
163
|
+
* @returns Array of valid target states
|
|
164
|
+
*/
|
|
165
|
+
getAvailableTransitions(): AgentState[];
|
|
166
|
+
/**
|
|
167
|
+
* Check if the agent is in a terminal state.
|
|
168
|
+
*
|
|
169
|
+
* Terminal states are states where the agent cannot make further
|
|
170
|
+
* progress without external intervention.
|
|
171
|
+
*
|
|
172
|
+
* @returns True if in a terminal state
|
|
173
|
+
*/
|
|
174
|
+
isTerminal(): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Check if the agent is in an active state (executing work).
|
|
177
|
+
*
|
|
178
|
+
* @returns True if the agent is actively working
|
|
179
|
+
*/
|
|
180
|
+
isActive(): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Check if the agent is in a waiting state.
|
|
183
|
+
*
|
|
184
|
+
* @returns True if the agent is waiting
|
|
185
|
+
*/
|
|
186
|
+
isWaiting(): boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Check if the agent is in a suspended or shutdown state.
|
|
189
|
+
*
|
|
190
|
+
* @returns True if the agent is suspended or shutting down
|
|
191
|
+
*/
|
|
192
|
+
isSuspendedOrShuttingDown(): boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Update lifecycle hooks.
|
|
195
|
+
*
|
|
196
|
+
* @param hooks - New hooks to merge with existing hooks
|
|
197
|
+
*/
|
|
198
|
+
setHooks(hooks: Partial<AgentLifecycleHooks>): void;
|
|
199
|
+
/**
|
|
200
|
+
* Reset the state machine to uninitialized state.
|
|
201
|
+
*
|
|
202
|
+
* This is primarily for testing purposes.
|
|
203
|
+
*/
|
|
204
|
+
reset(): void;
|
|
205
|
+
}
|