ultravisor-beacon 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/README.md ADDED
@@ -0,0 +1,100 @@
1
+ Ultravisor Beacon
2
+ =================
3
+
4
+ A lightweight beacon client and Fable service for remote task execution. Ultravisor Beacon turns any Node.js application into a distributed worker node that connects to an Ultravisor server, advertises capabilities, and executes work items on demand.
5
+
6
+ ## Features
7
+
8
+ - **Fable Service Integration** — Register as a service in any Fable/Pict application with `addAndInstantiateServiceType()`
9
+ - **Pluggable Providers** — Built-in Shell, FileSystem, and LLM providers; extend with custom providers via class, factory, or npm package
10
+ - **Automatic Transport** — Tries WebSocket for push-based dispatch, falls back to HTTP polling transparently
11
+ - **File Transfer** — Automatic source file download and output collection with affinity-scoped caching
12
+ - **Multi-Backend LLM** — Unified interface across OpenAI, Anthropic, Ollama, and OpenAI-compatible APIs
13
+ - **Resilient Connectivity** — Auto-reconnect with re-authentication on connection loss
14
+
15
+ ## Documentation
16
+
17
+ Comprehensive documentation is available in the [docs](./docs) folder:
18
+
19
+ - [Overview](./docs/README.md) — Introduction and getting started
20
+ - [Quick Start](./docs/quickstart.md) — Step-by-step setup guide
21
+ - [Architecture](./docs/architecture.md) — System design and mermaid diagrams
22
+ - [API Reference](./docs/api/README.md) — All classes and methods
23
+ - [Providers](./docs/providers/README.md) — Built-in and custom providers
24
+
25
+ ## Install
26
+
27
+ ```sh
28
+ $ npm install ultravisor-beacon
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### As a Fable Service
34
+
35
+ ```javascript
36
+ const libFable = require('fable');
37
+ const libBeacon = require('ultravisor-beacon');
38
+
39
+ let tmpFable = new libFable({ Product: 'MyApp', ProductVersion: '1.0.0' });
40
+
41
+ tmpFable.addAndInstantiateServiceType('UltravisorBeacon', libBeacon, {
42
+ ServerURL: 'http://localhost:54321',
43
+ Name: 'my-app-beacon'
44
+ });
45
+
46
+ let tmpBeacon = tmpFable.services.UltravisorBeacon;
47
+
48
+ tmpBeacon.registerCapability({
49
+ Capability: 'MyApp',
50
+ actions:
51
+ {
52
+ 'ProcessData':
53
+ {
54
+ Description: 'Process a data payload',
55
+ Handler: function (pWorkItem, pContext, fCallback)
56
+ {
57
+ let tmpResult = doSomeWork(pWorkItem.Settings);
58
+ return fCallback(null, { Outputs: { Result: tmpResult }, Log: ['Done.'] });
59
+ }
60
+ }
61
+ }
62
+ });
63
+
64
+ tmpBeacon.enable(function (pError, pBeacon)
65
+ {
66
+ console.log('Beacon online:', pBeacon.BeaconID);
67
+ });
68
+ ```
69
+
70
+ ### Standalone Client
71
+
72
+ ```javascript
73
+ const libBeaconClient = require('ultravisor-beacon').BeaconClient;
74
+
75
+ let tmpClient = new libBeaconClient({
76
+ ServerURL: 'http://localhost:54321',
77
+ Name: 'shell-worker',
78
+ Capabilities: ['Shell'],
79
+ MaxConcurrent: 4
80
+ });
81
+
82
+ tmpClient.start(function (pError, pBeacon)
83
+ {
84
+ console.log('Worker online:', pBeacon.BeaconID);
85
+ });
86
+ ```
87
+
88
+ ## Related Packages
89
+
90
+ - [fable](https://github.com/stevenvelozo/fable) — Service dependency injection framework
91
+ - [fable-serviceproviderbase](https://github.com/stevenvelozo/fable-serviceproviderbase) — Service provider base class
92
+ - [ultravisor](https://github.com/stevenvelozo/ultravisor) — Process supervision and orchestration server
93
+
94
+ ## License
95
+
96
+ MIT
97
+
98
+ ## Contributing
99
+
100
+ Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Ultravisor Beacon
2
+
3
+ > Lightweight beacon client and Fable service for remote task execution
4
+
5
+ Ultravisor Beacon turns any Node.js application into a distributed worker node. A beacon connects to an Ultravisor server, advertises the capabilities it can perform, and executes work items dispatched by the orchestrator. It handles authentication, transport negotiation, file transfer, and progress reporting so your application only needs to provide the business logic.
6
+
7
+ ## Features
8
+
9
+ - **Fable Service Integration** — Register as a service in any Fable/Pict application with `addAndInstantiateServiceType()`
10
+ - **Pluggable Providers** — Built-in Shell, FileSystem, and LLM providers; extend with custom providers via class, factory function, or npm package
11
+ - **Automatic Transport** — Tries WebSocket for push-based dispatch, falls back to HTTP polling transparently; reconnects on disconnect
12
+ - **File Transfer** — Automatic source file download and output collection with affinity-scoped caching for repeated operations
13
+ - **Multi-Backend LLM** — Unified interface across OpenAI, Anthropic, Ollama, and OpenAI-compatible APIs
14
+ - **Resilient Connectivity** — Auto-reconnect with re-authentication on connection loss; WebSocket-to-HTTP fallback
15
+
16
+ ## Quick Start
17
+
18
+ ```javascript
19
+ const libFable = require('fable');
20
+ const libBeacon = require('ultravisor-beacon');
21
+
22
+ let tmpFable = new libFable({ Product: 'MyApp' });
23
+
24
+ tmpFable.addAndInstantiateServiceType('UltravisorBeacon', libBeacon, {
25
+ ServerURL: 'http://localhost:54321',
26
+ Name: 'my-worker'
27
+ });
28
+
29
+ let tmpBeacon = tmpFable.services.UltravisorBeacon;
30
+
31
+ tmpBeacon.registerCapability({
32
+ Capability: 'DataProcessor',
33
+ actions:
34
+ {
35
+ 'Transform':
36
+ {
37
+ Description: 'Transform a data payload',
38
+ Handler: function (pWorkItem, pContext, fCallback)
39
+ {
40
+ let tmpInput = pWorkItem.Settings.Payload || '';
41
+ return fCallback(null, {
42
+ Outputs: { Result: tmpInput.toUpperCase() },
43
+ Log: ['Transformed payload.']
44
+ });
45
+ }
46
+ }
47
+ }
48
+ });
49
+
50
+ tmpBeacon.enable(function (pError, pBeacon)
51
+ {
52
+ if (pError) throw pError;
53
+ console.log('Beacon online:', pBeacon.BeaconID);
54
+ });
55
+ ```
56
+
57
+ ## Installation
58
+
59
+ ```bash
60
+ npm install ultravisor-beacon
61
+ ```
62
+
63
+ ## Core Concepts
64
+
65
+ ### Two Usage Modes
66
+
67
+ 1. **Fable Service** — Use `UltravisorBeaconService` to embed beacon functionality into an existing Fable application. Register capabilities with handler functions and call `enable()`.
68
+
69
+ 2. **Standalone Client** — Use `UltravisorBeaconClient` directly for headless worker nodes. Configure with provider descriptors and call `start()`.
70
+
71
+ ### Capabilities and Providers
72
+
73
+ A **capability** is a named unit of work a beacon can perform (e.g. `Shell`, `FileSystem`, `LLM`). Each capability has one or more **actions** (e.g. `Execute`, `Read`, `Write`).
74
+
75
+ A **provider** implements a capability. Built-in providers handle common tasks; custom providers extend `CapabilityProvider` for application-specific work.
76
+
77
+ ### Transport
78
+
79
+ Beacons auto-negotiate their transport:
80
+
81
+ 1. Try WebSocket — server pushes work items immediately
82
+ 2. Fall back to HTTP polling if WebSocket unavailable
83
+ 3. Reconnect automatically on disconnection
84
+
85
+ The coordinator does not track transport type. It checks for a live WebSocket when dispatching and falls through to the queue for polling beacons.
86
+
87
+ ## Documentation
88
+
89
+ - [Quick Start](quickstart.md) — Step-by-step setup
90
+ - [Architecture](architecture.md) — System design with diagrams
91
+ - [Providers](providers/README.md) — Built-in and custom providers
92
+ - [API Reference](api/README.md) — Complete class and method reference
93
+
94
+ ## Related Packages
95
+
96
+ - [fable](https://github.com/stevenvelozo/fable) — Service dependency injection framework
97
+ - [fable-serviceproviderbase](https://github.com/stevenvelozo/fable-serviceproviderbase) — Service provider base class
98
+ - [ultravisor](https://github.com/stevenvelozo/ultravisor) — Process supervision and orchestration server
package/docs/_cover.md ADDED
@@ -0,0 +1,12 @@
1
+ # Ultravisor Beacon <small>0.0.1</small>
2
+
3
+ > Lightweight beacon client and Fable service for remote task execution
4
+
5
+ - Pluggable capability providers (Shell, FileSystem, LLM, custom)
6
+ - Automatic WebSocket push with HTTP polling fallback
7
+ - File transfer with affinity-scoped caching
8
+ - First-class Fable ecosystem integration
9
+
10
+ [Get Started](quickstart.md)
11
+ [API Reference](api/README.md)
12
+ [GitHub](https://github.com/stevenvelozo/ultravisor-beacon)
@@ -0,0 +1,31 @@
1
+ - Getting Started
2
+
3
+ - [Introduction](/)
4
+ - [Quick Start](quickstart.md)
5
+ - [Architecture](architecture.md)
6
+
7
+ - Core Concepts
8
+
9
+ - [Providers Overview](providers/README.md)
10
+ - [Shell](providers/shell.md)
11
+ - [FileSystem](providers/filesystem.md)
12
+ - [LLM](providers/llm.md)
13
+
14
+ - API Reference
15
+
16
+ - [Overview](api/README.md)
17
+
18
+ - Service
19
+
20
+ - [BeaconService](api/beacon-service.md)
21
+ - [BeaconClient](api/beacon-client.md)
22
+
23
+ - Execution
24
+
25
+ - [Executor](api/executor.md)
26
+ - [ProviderRegistry](api/provider-registry.md)
27
+
28
+ - Capabilities
29
+
30
+ - [CapabilityManager](api/capability-manager.md)
31
+ - [CapabilityProvider](api/capability-provider.md)
@@ -0,0 +1,4 @@
1
+ [Home](/)
2
+ [Quick Start](quickstart.md)
3
+ [API Reference](api/README.md)
4
+ [GitHub](https://github.com/stevenvelozo/ultravisor-beacon)
@@ -0,0 +1,94 @@
1
+ # API Reference
2
+
3
+ Complete reference documentation for all public classes and methods in the Ultravisor Beacon module.
4
+
5
+ ## Module Exports
6
+
7
+ ```javascript
8
+ const libBeacon = require('ultravisor-beacon');
9
+ ```
10
+
11
+ The default export is `UltravisorBeaconService`. Sub-components are available as named properties:
12
+
13
+ | Export | Class | Description |
14
+ |--------|-------|-------------|
15
+ | *(default)* | [BeaconService](api/beacon-service.md) | Fable service wrapper |
16
+ | `.BeaconClient` | [BeaconClient](api/beacon-client.md) | Thin client for standalone workers |
17
+ | `.CapabilityManager` | [CapabilityManager](api/capability-manager.md) | Host app capability registry |
18
+ | `.CapabilityAdapter` | CapabilityAdapter | Descriptor-to-provider bridge |
19
+ | `.CapabilityProvider` | [CapabilityProvider](api/capability-provider.md) | Base class for providers |
20
+ | `.ProviderRegistry` | [ProviderRegistry](api/provider-registry.md) | Provider index and router |
21
+ | `.ConnectivityHTTP` | ConnectivityHTTP | HTTP transport configuration |
22
+ | `.ConnectivityWebSocket` | ConnectivityWebSocket | WebSocket transport configuration |
23
+
24
+ ## Class Hierarchy
25
+
26
+ ```
27
+ UltravisorBeaconService (extends FableServiceProviderBase)
28
+ ├── CapabilityManager
29
+ ├── ConnectivityHTTP
30
+ └── BeaconClient
31
+ └── Executor
32
+ └── ProviderRegistry
33
+ ├── Shell (extends CapabilityProvider)
34
+ ├── FileSystem (extends CapabilityProvider)
35
+ ├── LLM (extends CapabilityProvider)
36
+ └── CapabilityAdapter (extends CapabilityProvider)
37
+ ```
38
+
39
+ ## Common Patterns
40
+
41
+ ### Callback Convention
42
+
43
+ All async methods use Node.js-style callbacks:
44
+
45
+ ```javascript
46
+ function (pError, pResult) { ... }
47
+ ```
48
+
49
+ ### Work Item Shape
50
+
51
+ Work items passed to providers have this structure:
52
+
53
+ ```javascript
54
+ {
55
+ WorkItemHash: '0x1234abcd',
56
+ Capability: 'Shell',
57
+ Action: 'Execute',
58
+ Settings: { Command: 'echo hello', Parameters: '' },
59
+ TimeoutMs: 300000,
60
+ OperationHash: '0xabcd1234'
61
+ }
62
+ ```
63
+
64
+ ### Result Shape
65
+
66
+ Provider execution results follow this format:
67
+
68
+ ```javascript
69
+ {
70
+ Outputs:
71
+ {
72
+ StdOut: 'Command output text',
73
+ ExitCode: 0,
74
+ Result: 'Primary result value'
75
+ },
76
+ Log: ['Log message 1', 'Log message 2']
77
+ }
78
+ ```
79
+
80
+ ### Progress Reporting
81
+
82
+ Long-running operations can report progress:
83
+
84
+ ```javascript
85
+ fReportProgress({
86
+ Percent: 50,
87
+ Message: 'Halfway done',
88
+ Step: 3,
89
+ TotalSteps: 6,
90
+ Log: ['Step 3 complete']
91
+ });
92
+ ```
93
+
94
+ All fields are optional. The beacon client sends progress updates to the server via WebSocket or HTTP.
@@ -0,0 +1,176 @@
1
+ # BeaconClient
2
+
3
+ A lightweight worker node that connects to an Ultravisor server, registers its capabilities, and executes work items. Used directly for standalone workers or internally by `BeaconService`.
4
+
5
+ ## Constructor
6
+
7
+ ```javascript
8
+ const libBeaconClient = require('ultravisor-beacon').BeaconClient;
9
+
10
+ let tmpClient = new libBeaconClient(pConfig);
11
+ ```
12
+
13
+ ### Config
14
+
15
+ | Name | Type | Default | Description |
16
+ |------|------|---------|-------------|
17
+ | `ServerURL` | `string` | `'http://localhost:54321'` | Server endpoint |
18
+ | `Name` | `string` | `'beacon-worker'` | Worker name |
19
+ | `Password` | `string` | `''` | Authentication password |
20
+ | `Capabilities` | `string[]` | `['Shell']` | Legacy: built-in provider names to load |
21
+ | `Providers` | `object[]` | — | Provider descriptors: `[{ Source, Config }]` |
22
+ | `MaxConcurrent` | `number` | `1` | Max parallel work items |
23
+ | `PollIntervalMs` | `number` | `5000` | HTTP poll frequency (ms) |
24
+ | `HeartbeatIntervalMs` | `number` | `30000` | Heartbeat interval (ms) |
25
+ | `ReconnectIntervalMs` | `number` | `10000` | Reconnect delay (ms) |
26
+ | `StagingPath` | `string` | `process.cwd()` | Working directory for file transfer |
27
+ | `Tags` | `object` | `{}` | Metadata tags |
28
+
29
+ ### Provider Loading
30
+
31
+ If `Providers` is specified, the client loads each descriptor via `ProviderRegistry.loadProvider()`. Otherwise, the legacy `Capabilities` array is converted to provider descriptors automatically (e.g. `['Shell', 'FileSystem']` becomes `[{ Source: 'Shell' }, { Source: 'FileSystem' }]`).
32
+
33
+ ---
34
+
35
+ ## start()
36
+
37
+ Start the beacon client: initialize providers, authenticate, register, and begin accepting work.
38
+
39
+ ### Signature
40
+
41
+ ```javascript
42
+ client.start(fCallback)
43
+ ```
44
+
45
+ ### Callback
46
+
47
+ ```javascript
48
+ function (pError, pBeacon)
49
+ ```
50
+
51
+ | Name | Type | Description |
52
+ |------|------|-------------|
53
+ | `pError` | `Error\|null` | Error if start failed |
54
+ | `pBeacon` | `object` | `{ BeaconID: '...' }` on success |
55
+
56
+ ### Description
57
+
58
+ 1. Initialize all providers via `providerRegistry.initializeAll()`
59
+ 2. Authenticate with `POST /1.0/Authenticate`
60
+ 3. Try WebSocket transport (if `ws` library is available)
61
+ 4. Fall back to HTTP polling if WebSocket fails
62
+ 5. Begin heartbeat at `HeartbeatIntervalMs`
63
+
64
+ ### Transport Auto-Detection
65
+
66
+ The client automatically tries WebSocket first:
67
+
68
+ - If the `ws` npm package is installed and the server accepts the upgrade, the client registers over WebSocket and receives pushed work items.
69
+ - If WebSocket fails for any reason (library not installed, server doesn't support it, network blocks upgrades), the client falls back to HTTP polling transparently.
70
+ - No configuration flag is needed.
71
+
72
+ ### Example
73
+
74
+ ```javascript
75
+ let tmpClient = new libBeaconClient({
76
+ ServerURL: 'http://localhost:54321',
77
+ Name: 'my-worker',
78
+ Capabilities: ['Shell', 'FileSystem'],
79
+ MaxConcurrent: 4
80
+ });
81
+
82
+ tmpClient.start(function (pError, pBeacon)
83
+ {
84
+ if (pError)
85
+ {
86
+ console.error('Start failed:', pError.message);
87
+ return;
88
+ }
89
+ console.log('Worker online:', pBeacon.BeaconID);
90
+ });
91
+ ```
92
+
93
+ ---
94
+
95
+ ## stop()
96
+
97
+ Stop the beacon client: stop polling, close WebSocket, shutdown providers, deregister.
98
+
99
+ ### Signature
100
+
101
+ ```javascript
102
+ client.stop(fCallback)
103
+ ```
104
+
105
+ ### Callback
106
+
107
+ ```javascript
108
+ function (pError)
109
+ ```
110
+
111
+ | Name | Type | Description |
112
+ |------|------|-------------|
113
+ | `pError` | `Error\|null` | Error if shutdown had issues (non-fatal) |
114
+
115
+ ### Description
116
+
117
+ 1. Stop poll and heartbeat intervals
118
+ 2. Close WebSocket (sends `Deregister` message first)
119
+ 3. Clean up affinity staging directories
120
+ 4. Shut down all providers via `providerRegistry.shutdownAll()`
121
+ 5. Deregister from the server via `DELETE /Beacon/{id}`
122
+
123
+ ### Example
124
+
125
+ ```javascript
126
+ process.on('SIGTERM', function ()
127
+ {
128
+ tmpClient.stop(function (pError)
129
+ {
130
+ console.log('Worker stopped.');
131
+ process.exit(0);
132
+ });
133
+ });
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Reconnection
139
+
140
+ The client handles disconnection automatically:
141
+
142
+ **HTTP transport** — On a `401 Unauthorized` response, the client re-authenticates, re-registers, and restarts polling.
143
+
144
+ **WebSocket transport** — On connection close, the client:
145
+
146
+ 1. Re-authenticates (new session cookie)
147
+ 2. Tries WebSocket reconnection
148
+ 3. If WebSocket fails, falls back to HTTP polling
149
+ 4. If HTTP also fails, retries after `ReconnectIntervalMs`
150
+
151
+ No user intervention is needed. The beacon recovers silently.
152
+
153
+ ---
154
+
155
+ ## WebSocket Protocol
156
+
157
+ When connected via WebSocket, the client uses JSON messages:
158
+
159
+ ### Client → Server
160
+
161
+ | Action | Fields | Description |
162
+ |--------|--------|-------------|
163
+ | `BeaconRegister` | `Name`, `Capabilities`, `MaxConcurrent`, `Tags` | Register the beacon |
164
+ | `BeaconHeartbeat` | `BeaconID` | Keep-alive heartbeat |
165
+ | `WorkComplete` | `WorkItemHash`, `Outputs`, `Log` | Report successful execution |
166
+ | `WorkError` | `WorkItemHash`, `ErrorMessage`, `Log` | Report execution failure |
167
+ | `WorkProgress` | `WorkItemHash`, `ProgressData` | Report execution progress |
168
+ | `Deregister` | `BeaconID` | Deregister before disconnect |
169
+
170
+ ### Server → Client
171
+
172
+ | EventType | Fields | Description |
173
+ |-----------|--------|-------------|
174
+ | `BeaconRegistered` | `BeaconID` | Registration confirmation |
175
+ | `WorkItem` | `WorkItem` | Pushed work item to execute |
176
+ | `Deregistered` | — | Server-initiated deregistration |