@forgehive/hive-sdk 0.1.6 → 0.2.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 CHANGED
@@ -1,50 +1,23 @@
1
1
  # Hive SDK
2
2
 
3
- A TypeScript/JavaScript SDK for interacting with the Forge Hive logging and quality assessment platform.
4
-
5
- ## ⚠️ Deprecation Notices
6
-
7
- - **`sendLog()` method**: Deprecated. Use `sendLogByName()` or `sendLogByUuid()` instead.
8
- - **`projectName`-only configuration**: Deprecated. Use `createClientFromForgeConf()` or include `projectUuid` in your configuration.
9
-
10
- Future versions will require `projectUuid` and remove support for the legacy `sendLog()` method and name-based project identification.
3
+ A TypeScript/JavaScript SDK for interacting with the Forge Hive logging and task invocation platform.
11
4
 
12
5
  ## Quick Start
13
6
 
14
- Create a client from forge.json (recommended):
15
7
  ```typescript
16
8
  import { createClientFromForgeConf } from '@forgehive/hive-sdk'
17
9
 
18
- // Create client from forge.json (recommended)
10
+ // Create client from forge.json
19
11
  const client = createClientFromForgeConf('./forge.json', {
20
12
  metadata: {
21
13
  environment: 'production',
22
14
  version: '1.0.0'
23
15
  }
24
16
  })
25
- ```
26
17
 
27
- Or create with explicit configuration:
28
- ```typescript
29
- import { HiveLogClient } from '@forgehive/hive-sdk'
30
-
31
- // Create client with explicit configuration
32
- const client = new HiveLogClient({
33
- projectName: 'My Project',
34
- projectUuid: 'your-project-uuid',
35
- apiKey: 'your_api_key',
36
- apiSecret: 'your_api_secret'
37
- })
38
- ```
39
-
40
- On your app
41
-
42
- ```typescript
43
- // Run a task
44
- const [res, error, record] = await someTask.safeRun(args)
45
-
46
- // Send a log using task name (recommended)
47
- await client.sendLogByName('stock:getPrice', record)
18
+ // Run a task and send log
19
+ const [result, error, record] = await someTask.safeRun(args)
20
+ await client.sendLog(record, { environment: 'production' })
48
21
  ```
49
22
 
50
23
  ## Installation
@@ -59,236 +32,190 @@ or with pnpm:
59
32
  pnpm add @forgehive/hive-sdk
60
33
  ```
61
34
 
62
- ## Setup
35
+ ## Core Concepts
63
36
 
64
- ### 1. Configuration Options
37
+ The Hive SDK provides two main clients:
65
38
 
66
- The Hive SDK can be configured in two ways:
39
+ 1. **HiveLogClient** - For logging task execution records to Hive
40
+ 2. **HiveClient** - For invoking tasks remotely
67
41
 
68
- #### Option A: Explicit Configuration (Recommended)
69
-
70
- ```typescript
71
- import { HiveLogClient, createHiveLogClient } from '@forgehive/hive-sdk'
72
-
73
- // Direct configuration with credentials
74
- const config = {
75
- projectName: 'My Project',
76
- apiKey: 'your_api_key_here',
77
- apiSecret: 'your_api_secret_here',
78
- host: 'https://your-hive-instance.com', // Optional, defaults to https://www.forgehive.cloud
79
- metadata: { // Optional base metadata
80
- environment: 'production',
81
- version: '1.2.0'
82
- }
83
- }
42
+ ## HiveLogClient - Logging Task Executions
84
43
 
85
- const hiveLogger = new HiveLogClient(config)
86
- // or using the factory function
87
- const hiveLogger2 = createHiveLogClient(config)
88
- ```
44
+ ### Configuration
89
45
 
90
- #### Option B: Environment Variables (Fallback)
46
+ Create a client from your forge.json configuration file:
91
47
 
92
- If you prefer environment variables, the SDK will automatically use them when no explicit credentials are provided:
48
+ ```typescript
49
+ import { createClientFromForgeConf } from '@forgehive/hive-sdk'
93
50
 
94
- ```bash
95
- HIVE_API_KEY=your_api_key_here
96
- HIVE_API_SECRET=your_api_secret_here
97
- HIVE_HOST=https://your-hive-instance.com # Optional, defaults to https://www.forgehive.cloud
98
- ```
51
+ // Use default forge.json path (./forge.json)
52
+ const client = createClientFromForgeConf()
99
53
 
100
- ```typescript
101
- import { HiveLogClient } from '@forgehive/hive-sdk'
54
+ // Or specify a custom path
55
+ const client = createClientFromForgeConf('./config/forge.json')
102
56
 
103
- // Uses environment variables for credentials
104
- const hiveLogger = new HiveLogClient({
105
- projectName: 'My Project',
57
+ // Add additional metadata
58
+ const client = createClientFromForgeConf('./forge.json', {
106
59
  metadata: {
107
60
  environment: 'production',
108
- version: '1.2.0'
61
+ version: '1.0.0'
109
62
  }
110
63
  })
111
64
  ```
112
65
 
113
- You can get your API credentials at [https://www.forgehive.cloud](https://www.forgehive.cloud).
66
+ **Benefits:**
67
+ - Automatically loads project name and UUID from forge.json
68
+ - Automatically loads task UUIDs for logging
69
+ - Supports task verification with `testConfig()`
70
+ - Reduces configuration boilerplate
114
71
 
115
- ### 2. Basic Usage
72
+ **API Credentials:**
116
73
 
117
- ```typescript
118
- import { HiveLogClient, createHiveLogClient } from '@forgehive/hive-sdk'
74
+ Set your API credentials using environment variables:
119
75
 
120
- // Create client with explicit config
121
- const hiveLogger = new HiveLogClient({
122
- projectName: 'Personal Knowledge Management System',
123
- apiKey: 'your_api_key',
124
- apiSecret: 'your_api_secret',
125
- metadata: {
126
- environment: 'production',
127
- version: '1.2.0',
128
- team: 'backend'
129
- }
130
- })
131
-
132
- // Or using factory function
133
- const hiveLogger2 = createHiveLogClient({
134
- projectName: 'Personal Knowledge Management System',
135
- metadata: {
136
- environment: 'production',
137
- version: '1.2.0',
138
- team: 'backend'
139
- }
140
- })
76
+ ```bash
77
+ HIVE_API_KEY=your_api_key_here
78
+ HIVE_API_SECRET=your_api_secret_here
79
+ HIVE_HOST=https://www.forgehive.cloud # Optional
141
80
  ```
142
81
 
143
- ## API Methods
82
+ You can get your API credentials at [https://www.forgehive.cloud](https://www.forgehive.cloud).
144
83
 
145
- ### `new HiveLogClient(config: HiveLogClientConfig): HiveLogClient`
84
+ ### Basic Usage
146
85
 
147
- Creates a new Hive log client instance with configuration object.
86
+ #### Manual Logging
148
87
 
149
88
  ```typescript
150
- import { HiveLogClient, HiveLogClientConfig, Metadata } from '@forgehive/hive-sdk'
89
+ import { createClientFromForgeConf } from '@forgehive/hive-sdk'
90
+ import { myTask } from './tasks/myTask'
151
91
 
152
- // Minimal configuration (uses environment variables for credentials)
153
- const client = new HiveLogClient({
154
- projectName: 'My Project'
155
- })
92
+ // Create client
93
+ const client = createClientFromForgeConf('./forge.json')
156
94
 
157
- // Full configuration with explicit credentials
158
- const config: HiveLogClientConfig = {
159
- projectName: 'My Project',
160
- apiKey: 'your_api_key',
161
- apiSecret: 'your_api_secret',
162
- host: 'https://your-hive-instance.com', // Optional, defaults to https://www.forgehive.cloud
163
- metadata: {
95
+ // Run task
96
+ const [result, error, record] = await myTask.safeRun({ input: 'data' })
97
+
98
+ // Manually send log
99
+ if (record) {
100
+ const status = await client.sendLog(record, {
164
101
  environment: 'production',
165
- version: '2.1.0',
166
- datacenter: 'us-east-1'
167
- }
102
+ requestId: 'req-123'
103
+ })
104
+ console.log('Log status:', status) // 'success', 'error', or 'silent'
168
105
  }
169
- const clientWithConfig = new HiveLogClient(config)
170
106
  ```
171
107
 
172
- **Configuration Object:**
173
- - `projectName`: Name of your project (required, ⚠️ deprecated - use `createClientFromForgeConf` instead)
174
- - `projectUuid`: UUID of your project (recommended for new implementations)
175
- - `apiKey`: API key (optional, falls back to `HIVE_API_KEY` environment variable)
176
- - `apiSecret`: API secret (optional, falls back to `HIVE_API_SECRET` environment variable)
177
- - `host`: Hive instance URL (optional, falls back to `HIVE_HOST` environment variable, then defaults to `https://www.forgehive.cloud`)
178
- - `metadata`: Base metadata that will be included with every log (optional)
179
- - `forgeConfigPath`: Path to forge.json file (optional, defaults to './forge.json')
180
-
181
- **Returns:** `HiveLogClient` - Configured client instance
182
-
183
- ### `createClientFromForgeConf(forgeConfigPath?: string, additionalConfig?: Partial<HiveLogClientConfig>): HiveLogClient` (Recommended)
184
-
185
- Creates a Hive log client automatically configured from your forge.json file. This is the recommended way to create clients as it automatically loads project name, UUID, and task configurations.
108
+ #### Automatic Logging with Global Listener
186
109
 
187
110
  ```typescript
111
+ import { Task } from '@forgehive/task'
188
112
  import { createClientFromForgeConf } from '@forgehive/hive-sdk'
189
113
 
190
- // Use default forge.json path (./forge.json)
191
- const client = createClientFromForgeConf()
114
+ // Create client
115
+ const client = createClientFromForgeConf('./forge.json')
192
116
 
193
- // Use custom forge.json path
194
- const client = createClientFromForgeConf('./config/forge.json')
117
+ // Set up global listener - automatically logs ALL task executions
118
+ Task.listenExecutionRecords(client.getListener())
195
119
 
196
- // Use default path with additional config
197
- const client = createClientFromForgeConf(undefined, {
198
- metadata: {
199
- environment: 'production',
200
- version: '1.0.0'
201
- }
202
- })
203
-
204
- // Use custom path with additional config
205
- const client = createClientFromForgeConf('./forge.json', {
206
- apiKey: 'override-key', // Override any forge.json values
207
- metadata: {
208
- environment: 'production'
209
- }
210
- })
120
+ // All task executions will now be automatically logged
121
+ const [result1] = await task1.safeRun(args) // Automatically logged
122
+ const [result2] = await task2.safeRun(args) // Automatically logged
211
123
  ```
212
124
 
125
+ ## API Reference - HiveLogClient
126
+
127
+ ### `createClientFromForgeConf(forgeConfigPath?: string, additionalConfig?: Partial<HiveLogClientConfig>): HiveLogClient`
128
+
129
+ Creates a Hive log client automatically configured from your forge.json file.
130
+
213
131
  **Parameters:**
214
132
  - `forgeConfigPath` (optional): Path to forge.json file (defaults to './forge.json')
215
133
  - `additionalConfig` (optional): Additional config to override forge.json values
216
134
 
217
- **Returns:** `HiveLogClient` - Configured client with project name, UUID, and task mappings from forge.json
218
-
219
- **Benefits:**
220
- - Automatically loads project name and UUID from forge.json
221
- - Enables `sendLogByName()` method for easy task logging
222
- - Supports task verification with `testConfig()`
223
- - Reduces configuration boilerplate
135
+ **Returns:** `HiveLogClient`
224
136
 
225
137
  ### `createHiveLogClient(config: HiveLogClientConfig): HiveLogClient`
226
138
 
227
- Factory function that creates a new Hive log client instance with explicit configuration.
228
-
229
- ```typescript
230
- import { createHiveLogClient } from '@forgehive/hive-sdk'
231
-
232
- const client = createHiveLogClient({
233
- projectName: 'My Project',
234
- apiKey: 'your_api_key',
235
- apiSecret: 'your_api_secret',
236
- metadata: {
237
- environment: 'production',
238
- team: 'backend'
239
- }
240
- })
241
- ```
139
+ Factory function that creates a new Hive log client instance.
242
140
 
243
- **Parameters:** Same as `HiveLogClient` constructor
244
- **Returns:** `HiveLogClient` - Configured client instance
141
+ **Configuration Object:**
142
+ - `projectName` (required): Name of your project
143
+ - `projectUuid` (optional but recommended): UUID of your project
144
+ - `apiKey` (optional): API key (falls back to `HIVE_API_KEY` env var)
145
+ - `apiSecret` (optional): API secret (falls back to `HIVE_API_SECRET` env var)
146
+ - `host` (optional): Hive instance URL (defaults to `https://www.forgehive.cloud`)
147
+ - `metadata` (optional): Base metadata included with every log
148
+ - `forgeConfigPath` (optional): Path to forge.json file (defaults to './forge.json')
245
149
 
246
- ### `sendLog(record: ExecutionRecord, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>` ⚠️ DEPRECATED
150
+ **Returns:** `HiveLogClient`
247
151
 
248
- > **⚠️ DEPRECATION WARNING**: `sendLog()` is deprecated and will be removed in a future version. Use `sendLogByName()` or `sendLogByUuid()` instead for better performance and enhanced features.
152
+ ### `client.sendLog(record: ExecutionRecord, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>`
249
153
 
250
- Sends a log entry to Hive using the legacy endpoint. This method still works but lacks the enhanced features of the newer UUID-based endpoints.
154
+ Sends a log entry to Hive. Requires `projectUuid` to be set in client configuration.
251
155
 
252
156
  ```typescript
253
- // DEPRECATED - Use sendLogByName() instead
254
- const status = await client.sendLog(record, metadata)
157
+ const [result, error, record] = await myTask.safeRun(args)
158
+
159
+ if (record) {
160
+ const status = await client.sendLog(record, {
161
+ environment: 'production',
162
+ requestId: 'req-123'
163
+ })
255
164
 
256
- // RECOMMENDED - Use sendLogByName() for automatic UUID lookup
257
- const status = await client.sendLogByName('stock:getPrice', record, metadata)
165
+ switch (status) {
166
+ case 'success':
167
+ console.log('Log sent successfully')
168
+ break
169
+ case 'error':
170
+ console.error('Failed to send log')
171
+ break
172
+ case 'silent':
173
+ console.log('Running in silent mode - no credentials')
174
+ break
175
+ }
176
+ }
258
177
  ```
259
178
 
260
- ### `sendLogByName(taskName: string, record: ExecutionRecord, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>` (Recommended)
179
+ **Parameters:**
180
+ - `record`: ExecutionRecord from task execution
181
+ - `metadata` (optional): Additional metadata for this log
261
182
 
262
- Sends a log entry to Hive using task name for automatic UUID lookup. Requires `projectUuid` to be set and forge.json to be loaded.
183
+ **Returns:**
184
+ - `'success'` - Log sent successfully
185
+ - `'error'` - Network or API error
186
+ - `'silent'` - Client not initialized (no credentials)
187
+ - `LogApiSuccess` - Full API response with log details
263
188
 
264
- ```typescript
265
- // Run a task and send log by name
266
- const [result, error, record] = await myTask.safeRun(args)
267
- const status = await client.sendLogByName('stock:getPrice', record, {
268
- environment: 'production',
269
- requestId: 'req-123'
270
- })
271
- ```
272
-
273
- ### `sendLogByUuid(record: ExecutionRecord, taskUuid: string, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>`
189
+ ### `client.getListener(): (record: ExecutionRecord) => Promise<void>`
274
190
 
275
- Sends a log entry to Hive using explicit task UUID. Requires `projectUuid` to be set in client config.
191
+ Returns a listener function that can be passed to `Task.listenExecutionRecords()` for automatic logging.
276
192
 
277
193
  ```typescript
278
- const status = await client.sendLogByUuid(record, 'a45aafe3-8b01-4b58-b15d-9a96274858ee', metadata)
194
+ import { Task } from '@forgehive/task'
195
+
196
+ // Set up global automatic logging
197
+ Task.listenExecutionRecords(client.getListener())
279
198
  ```
280
199
 
281
- ### `testConfig(): Promise<TestConfigResult>`
200
+ ### `client.testConfig(): Promise<TestConfigResult>`
282
201
 
283
202
  Tests the client configuration by verifying credentials, project access, and task synchronization.
284
203
 
285
204
  ```typescript
286
205
  const result = await client.testConfig()
287
206
  console.log('Config test:', result)
288
- // Returns: { success, teamName, userName, projectName, projectExists, tasksVerified, error? }
207
+ // Returns: {
208
+ // success: boolean
209
+ // teamName?: string
210
+ // userName?: string
211
+ // projectName?: string
212
+ // projectExists?: boolean
213
+ // tasksVerified?: { total: number, found: number, missing: string[] }
214
+ // error?: string
215
+ // }
289
216
  ```
290
217
 
291
- ### `getConf(): Record<string, unknown>`
218
+ ### `client.getConf(): Record<string, unknown>`
292
219
 
293
220
  Returns the client configuration with masked secrets (shows first 4 + last 4 characters).
294
221
 
@@ -298,281 +225,198 @@ console.log('Client config:', config)
298
225
  // Returns: { projectName, projectUuid, host, apiKey: 'abcd****wxyz', ... }
299
226
  ```
300
227
 
301
- ### `isActive(): boolean`
228
+ ### `client.isActive(): boolean`
302
229
 
303
230
  Check if the client is properly initialized with credentials.
304
231
 
305
232
  ```typescript
306
- const hiveLogger = new HiveLogClient({
307
- projectName: 'My Project',
308
- apiKey: 'your_api_key',
309
- apiSecret: 'your_api_secret'
310
- })
311
-
312
- if (hiveLogger.isActive()) {
233
+ if (client.isActive()) {
313
234
  console.log('Client is initialized with credentials')
314
- // Safe to call getLog and setQuality without try/catch
315
235
  } else {
316
236
  console.log('Client is in silent mode')
317
- // Only sendLog will work (returns 'silent')
318
237
  }
319
238
  ```
320
239
 
321
- **Returns:** `boolean` - `true` if credentials are available, `false` if in silent mode
322
-
323
- ### `sendLog(taskName: string, logItem: LogItemInput, metadata?: Metadata): Promise<'success' | 'error' | 'silent'>`
240
+ ### `client.getLog(taskName: string, uuid: string): Promise<LogApiResult | null>`
324
241
 
325
- Sends a log entry to Hive for a specific task with optional metadata. Accepts both manual log items and task execution records.
242
+ Retrieves a specific log entry from Hive.
326
243
 
327
244
  ```typescript
328
- // Using a manual log item
329
- const status = await hiveLogger.sendLogByName('user-authentication', {
330
- input: { username: 'john_doe', timestamp: Date.now() },
331
- output: { success: true, userId: 12345 },
332
- boundaries: {
333
- database: [
334
- {
335
- input: 'SELECT * FROM users WHERE username = ?',
336
- output: [{ id: 12345, username: 'john_doe' }],
337
- error: null
338
- }
339
- ]
340
- }
341
- }, {
342
- // This metadata has highest priority
343
- requestId: 'req-123',
344
- userId: 'user-456'
345
- })
346
-
347
- // Using a task execution record directly
348
- const [result, error, record] = await someTask.safeRun(args)
349
- await hiveLogger.sendLogByName('task-name', record, {
350
- environment: 'production'
351
- })
245
+ const logData = await client.getLog('stock:getPrice', 'log-uuid-123')
352
246
 
353
- switch (status) {
354
- case 'success':
355
- console.log('Log sent successfully')
356
- break
357
- case 'error':
358
- console.error('Failed to send log - network or API error')
359
- break
360
- case 'silent':
361
- console.log('Running in silent mode - no credentials configured')
362
- break
247
+ if (logData && !isApiError(logData)) {
248
+ console.log('Log retrieved:', logData.logItem)
249
+ } else if (logData && isApiError(logData)) {
250
+ console.error('API Error:', logData.error)
363
251
  }
364
252
  ```
365
253
 
366
254
  **Parameters:**
367
- - `taskName`: Name of the task being logged
368
- - `logItem`: LogItemInput object (supports both manual log items and task execution records)
369
- - `metadata` (optional): Additional metadata for this specific log
255
+ - `taskName`: Name of the task
256
+ - `uuid`: Unique identifier of the log entry
370
257
 
371
- **Returns:** `Promise<'success' | 'error' | 'silent'>` - Status of the operation
258
+ **Returns:** `Promise<LogApiResult | null>`
372
259
 
373
- ### `getLog(taskName: string, uuid: string): Promise<LogApiResult | null>`
260
+ **Throws:** Error when credentials are missing
374
261
 
375
- Retrieves a specific log entry from Hive.
262
+ ### `client.setQuality(taskName: string, uuid: string, quality: Quality): Promise<boolean>`
263
+
264
+ Sets a quality assessment for a specific log entry.
376
265
 
377
266
  ```typescript
378
- try {
379
- const logData = await hiveLogger.getLog('user-authentication', 'log-uuid-123')
380
-
381
- if (logData && !isApiError(logData)) {
382
- console.log('Log retrieved:', logData.logItem)
383
- console.log('Log metadata:', logData.logItem.metadata)
384
- } else if (logData && isApiError(logData)) {
385
- console.error('API Error:', logData.error)
386
- } else {
387
- console.error('Failed to retrieve log')
388
- }
389
- } catch (error) {
390
- console.error('Missing credentials:', error.message)
267
+ import { Quality } from '@forgehive/hive-sdk'
268
+
269
+ const quality: Quality = {
270
+ score: 8.5,
271
+ reason: 'Good performance with minor improvements needed',
272
+ suggestions: 'Consider optimizing the database query'
391
273
  }
274
+
275
+ const success = await client.setQuality('stock:getPrice', 'log-uuid-123', quality)
392
276
  ```
393
277
 
394
278
  **Parameters:**
395
279
  - `taskName`: Name of the task
396
280
  - `uuid`: Unique identifier of the log entry
281
+ - `quality`: Quality assessment object
282
+
283
+ **Returns:** `Promise<boolean>` - `true` if successful, `false` if failed
397
284
 
398
- **Returns:** `Promise<LogApiResult | null>` - Log data, error object, or `null` if failed
399
285
  **Throws:** Error when credentials are missing
400
286
 
401
- ### `setQuality(taskName: string, uuid: string, quality: Quality): Promise<boolean>`
287
+ ## HiveClient - Task Invocation
402
288
 
403
- Sets a quality assessment for a specific log entry.
289
+ ### Configuration
404
290
 
405
291
  ```typescript
406
- import { Quality } from '@forgehive/hive-sdk'
292
+ import { createHiveClient } from '@forgehive/hive-sdk'
407
293
 
408
- const quality: Quality = {
409
- score: 8.5,
410
- reason: 'Good performance with minor improvements needed',
411
- suggestions: 'Consider optimizing the database query for better performance'
412
- }
294
+ const client = createHiveClient({
295
+ projectUuid: 'your-project-uuid',
296
+ apiKey: 'your_api_key',
297
+ apiSecret: 'your_api_secret',
298
+ host: 'https://www.forgehive.cloud' // Optional
299
+ })
300
+ ```
413
301
 
414
- try {
415
- const success = await hiveLogger.setQuality('user-authentication', 'log-uuid-123', quality)
302
+ **Configuration Object:**
303
+ - `projectUuid` (required): UUID of your project
304
+ - `apiKey` (optional): API key (falls back to `HIVE_API_KEY` env var)
305
+ - `apiSecret` (optional): API secret (falls back to `HIVE_API_SECRET` env var)
306
+ - `host` (optional): Hive instance URL (defaults to `https://forgehive.dev`)
416
307
 
417
- if (success) {
418
- console.log('Quality assessment saved')
419
- } else {
420
- console.error('Failed to save quality assessment')
421
- }
422
- } catch (error) {
423
- console.error('Missing credentials:', error.message)
308
+ ### `client.invoke(taskUuid: string, payload: unknown): Promise<InvokeResult | null>`
309
+
310
+ Invokes a task remotely on the Hive platform.
311
+
312
+ ```typescript
313
+ import { createHiveClient, isInvokeError } from '@forgehive/hive-sdk'
314
+
315
+ const client = createHiveClient({
316
+ projectUuid: process.env.HIVE_PROJECT_UUID || ''
317
+ })
318
+
319
+ const result = await client.invoke('task-uuid-here', {
320
+ ticker: 'AAPL'
321
+ })
322
+
323
+ if (isInvokeError(result)) {
324
+ console.error('Error invoking task:', result.error)
325
+ } else {
326
+ console.log('Success:', result.responsePayload)
424
327
  }
425
328
  ```
426
329
 
427
330
  **Parameters:**
428
- - `taskName`: Name of the task
429
- - `uuid`: Unique identifier of the log entry
430
- - `quality`: Quality assessment object with score (number), reason (string), and suggestions (string)
331
+ - `taskUuid`: UUID of the task to invoke
332
+ - `payload`: Input data for the task
431
333
 
432
- **Returns:** `Promise<boolean>` - `true` if successful, `false` if failed
433
- **Throws:** Error when credentials are missing
334
+ **Returns:** `Promise<InvokeResult | null>`
335
+ - `{ responsePayload: unknown }` - Success response
336
+ - `{ error: string }` - Error response
337
+ - `null` - Network error
434
338
 
435
- ## Metadata System
339
+ ### `client.testConfig(): Promise<TestConfigResult>`
436
340
 
437
- The Hive SDK supports a flexible metadata system that allows you to attach contextual information to your logs. Metadata can be provided at three levels with a clear priority system.
341
+ Tests the client configuration by verifying credentials and project access.
438
342
 
439
- ### Metadata Priority System
343
+ ### `client.getConf(): Record<string, unknown>`
440
344
 
441
- Metadata is merged using the following priority order (highest to lowest):
345
+ Returns the client configuration with masked secrets.
442
346
 
443
- 1. **sendLogByName metadata** - Metadata passed directly to the `sendLogByName` method
444
- 2. **logItem metadata** - Metadata already present in the `logItem` object
347
+ ## Metadata System
348
+
349
+ The Hive SDK supports a flexible metadata system with a clear priority order:
350
+
351
+ ### Metadata Priority (highest to lowest)
352
+
353
+ 1. **sendLog metadata** - Metadata passed directly to `sendLog()`
354
+ 2. **Record metadata** - Metadata in the ExecutionRecord
445
355
  3. **Client base metadata** - Metadata set when creating the client
446
356
 
357
+ ### Example
358
+
447
359
  ```typescript
448
360
  // Create client with base metadata
449
- const client = new HiveLogClient({
450
- projectName: 'My Project',
451
- apiKey: 'your_api_key',
452
- apiSecret: 'your_api_secret',
361
+ const client = createClientFromForgeConf('./forge.json', {
453
362
  metadata: {
454
363
  environment: 'production',
455
- version: '1.0.0',
456
- team: 'backend'
364
+ version: '1.0.0'
457
365
  }
458
366
  })
459
367
 
460
- // logItem with metadata
461
- const logItem = {
462
- input: 'test input',
463
- output: 'test output',
368
+ // Record with metadata
369
+ const record = {
370
+ taskName: 'myTask',
371
+ input: {},
372
+ output: {},
373
+ type: 'success',
374
+ boundaries: {},
464
375
  metadata: {
465
376
  sessionId: 'session-123',
466
- version: '1.1.0' // This overrides client version
377
+ version: '1.1.0' // Overrides client version
467
378
  }
468
379
  }
469
380
 
470
- // Send log with additional metadata
471
- await client.sendLogByName('task-name', logItem, {
381
+ // Send log with metadata
382
+ await client.sendLog(record, {
472
383
  requestId: 'req-456',
473
- version: '1.2.0' // This overrides both logItem and client version
384
+ version: '1.2.0' // Overrides all (highest priority)
474
385
  })
475
386
 
476
- // Final metadata sent will be:
387
+ // Final metadata sent:
477
388
  // {
478
389
  // environment: 'production', // from client
479
- // team: 'backend', // from client
480
- // sessionId: 'session-123', // from logItem
481
- // version: '1.2.0', // from sendLogByName (highest priority)
482
- // requestId: 'req-456' // from sendLogByName
390
+ // sessionId: 'session-123', // from record
391
+ // version: '1.2.0', // from sendLog (highest priority)
392
+ // requestId: 'req-456' // from sendLog
483
393
  // }
484
394
  ```
485
395
 
486
- ### Metadata Usage Examples
487
-
488
- **Base metadata for all logs:**
489
- ```typescript
490
- const client = new HiveLogClient({
491
- projectName: 'My Service',
492
- apiKey: 'your_api_key',
493
- apiSecret: 'your_api_secret',
494
- metadata: {
495
- environment: process.env.NODE_ENV,
496
- version: process.env.APP_VERSION,
497
- datacenter: 'us-west-2'
498
- }
499
- })
500
- ```
501
-
502
- **Request-specific metadata:**
503
- ```typescript
504
- app.post('/api/users', async (req, res) => {
505
- const result = await client.sendLogByName('create-user', {
506
- input: req.body,
507
- output: newUser
508
- }, {
509
- requestId: req.headers['x-request-id'],
510
- userId: req.user?.id,
511
- ipAddress: req.ip
512
- })
513
- })
514
- ```
515
-
516
- **logItem with embedded metadata:**
517
- ```typescript
518
- const logItem = {
519
- input: { query: 'search term' },
520
- output: { results: [...] },
521
- metadata: {
522
- searchDuration: '245', // ms
523
- resultCount: '15',
524
- algorithm: 'fuzzy-v2'
525
- }
526
- }
527
-
528
- await client.sendLogByName('search', logItem)
529
- ```
530
-
531
396
  ## Types
532
397
 
533
398
  ### `HiveLogClientConfig`
534
399
 
535
400
  ```typescript
536
401
  interface HiveLogClientConfig {
537
- projectName: string // ⚠️ DEPRECATED - use createClientFromForgeConf() instead
538
- projectUuid?: string // Recommended for new implementations
402
+ projectName: string
403
+ projectUuid?: string // Recommended
539
404
  apiKey?: string
540
405
  apiSecret?: string
541
406
  host?: string
542
407
  metadata?: Metadata
543
- forgeConfigPath?: string // Path to forge.json file
408
+ forgeConfigPath?: string
544
409
  }
545
410
  ```
546
411
 
547
- **⚠️ Migration Guide:**
548
- ```typescript
549
- // OLD (deprecated) - projectName only
550
- const client = new HiveLogClient({
551
- projectName: 'My Project'
552
- })
553
-
554
- // NEW (recommended) - use createClientFromForgeConf
555
- const client = createClientFromForgeConf('./forge.json')
556
-
557
- // NEW (alternative) - explicit projectUuid
558
- const client = new HiveLogClient({
559
- projectName: 'My Project',
560
- projectUuid: 'your-project-uuid'
561
- })
562
- ```
563
-
564
- ### `LogItemInput` (also exported as `LogItem`)
412
+ ### `HiveClientConfig`
565
413
 
566
414
  ```typescript
567
- interface LogItemInput {
568
- input: unknown
569
- output?: unknown
570
- error?: unknown
571
- boundaries?: unknown // Flexible to accept different boundary structures
572
- metadata?: Metadata
573
- taskName?: string
574
- type?: string
575
- [key: string]: unknown // Allows task execution records and other additional properties
415
+ interface HiveClientConfig {
416
+ projectUuid: string // Required
417
+ apiKey?: string
418
+ apiSecret?: string
419
+ host?: string
576
420
  }
577
421
  ```
578
422
 
@@ -584,25 +428,6 @@ interface Metadata {
584
428
  }
585
429
  ```
586
430
 
587
- ### `LogApiResponse`
588
-
589
- ```typescript
590
- interface LogApiResponse {
591
- uuid: string
592
- taskName: string
593
- projectName: string
594
- logItem: {
595
- input: unknown
596
- output?: unknown
597
- error?: unknown
598
- boundaries?: Record<string, Array<{ input: unknown; output: unknown, error: unknown }>>
599
- metadata?: Metadata
600
- }
601
- replayFrom?: string
602
- createdAt: string
603
- }
604
- ```
605
-
606
431
  ### `Quality`
607
432
 
608
433
  ```typescript
@@ -613,6 +438,22 @@ interface Quality {
613
438
  }
614
439
  ```
615
440
 
441
+ ### `InvokeResponse`
442
+
443
+ ```typescript
444
+ interface InvokeResponse {
445
+ responsePayload: unknown
446
+ }
447
+ ```
448
+
449
+ ### `InvokeError`
450
+
451
+ ```typescript
452
+ interface InvokeError {
453
+ error: string
454
+ }
455
+ ```
456
+
616
457
  ### `ApiError`
617
458
 
618
459
  ```typescript
@@ -625,12 +466,12 @@ interface ApiError {
625
466
 
626
467
  ### `isApiError(response: unknown): response is ApiError`
627
468
 
628
- Use this type guard to check if a response is an error:
469
+ Check if a response is an API error:
629
470
 
630
471
  ```typescript
631
472
  import { isApiError } from '@forgehive/hive-sdk'
632
473
 
633
- const result = await hiveLogger.getLog('task-name', 'log-uuid')
474
+ const result = await client.getLog('task-name', 'log-uuid')
634
475
 
635
476
  if (result && isApiError(result)) {
636
477
  console.error('Error:', result.error)
@@ -639,9 +480,25 @@ if (result && isApiError(result)) {
639
480
  }
640
481
  ```
641
482
 
483
+ ### `isInvokeError(response: unknown): response is InvokeError`
484
+
485
+ Check if an invoke response is an error:
486
+
487
+ ```typescript
488
+ import { isInvokeError } from '@forgehive/hive-sdk'
489
+
490
+ const result = await client.invoke('task-uuid', payload)
491
+
492
+ if (isInvokeError(result)) {
493
+ console.error('Error:', result.error)
494
+ } else {
495
+ console.log('Success:', result.responsePayload)
496
+ }
497
+ ```
498
+
642
499
  ## Debugging
643
500
 
644
- The SDK uses the `debug` package for internal logging. To enable debug logs, set the `DEBUG` environment variable:
501
+ The SDK uses the `debug` package for internal logging. To enable debug logs:
645
502
 
646
503
  ```bash
647
504
  # Enable all hive-sdk debug logs
@@ -649,28 +506,15 @@ DEBUG=hive-sdk node your-app.js
649
506
 
650
507
  # Enable all debug logs
651
508
  DEBUG=* node your-app.js
652
-
653
- # Enable hive-sdk logs along with other specific loggers
654
- DEBUG=hive-sdk,express:* node your-app.js
655
509
  ```
656
510
 
657
- When debugging is enabled, you'll see detailed logs like:
511
+ Example debug output:
658
512
 
659
513
  ```
660
- # Normal mode (with credentials)
661
- hive-sdk Creating HiveLogClient for project "Personal Knowledge Management System" +0ms
662
- hive-sdk HiveLogClient initialized for project "Personal Knowledge Management System" with host "https://your-hive-instance.com" +2ms
663
- hive-sdk Sending log for task "user-authentication" to https://your-hive-instance.com/api/tasks/log-ingest +100ms
664
- hive-sdk Success: Sent log for task "user-authentication" +250ms
665
-
666
- # Silent mode (missing credentials)
667
- hive-sdk Creating HiveLogClient for project "Personal Knowledge Management System" +0ms
668
- hive-sdk HiveLogClient in silent mode for project "Personal Knowledge Management System" - missing credentials (get them at https://www.forgehive.cloud) +2ms
669
- hive-sdk Silent mode: Skipping sendLog for task "user-authentication" - client not initialized +100ms
670
- hive-sdk Error: getLog for task "user-task" with uuid "some-uuid" - missing credentials +150ms
671
-
672
- # Error handling
673
- hive-sdk Error: Failed to send log for task "another-task": Network timeout +300ms
514
+ hive-sdk Creating HiveLogClient for project "My Project" +0ms
515
+ hive-sdk HiveLogClient initialized for project "My Project" with host "https://www.forgehive.cloud" +2ms
516
+ hive-sdk Sending log for task "stock:getPrice" (UUID: xxx) to https://www.forgehive.cloud/api/log-ingest +100ms
517
+ hive-sdk Success: Sent log for task "stock:getPrice" (UUID: xxx) +250ms
674
518
  ```
675
519
 
676
520
  ## Error Handling
@@ -679,132 +523,78 @@ The SDK handles errors gracefully:
679
523
 
680
524
  - **Network errors**: Logged via debug, methods return `'error'` or `false`
681
525
  - **Authentication errors**: Logged via debug, methods return `'error'` or `false`
682
- - **API errors**: Returned as `ApiError` objects (for `getLog`) or logged via debug (for other methods)
683
526
  - **Missing credentials**:
684
527
  - `sendLog`: Returns `'silent'` (no errors thrown)
685
528
  - `getLog` and `setQuality`: Throw errors
529
+ - `invoke`: Requires credentials, throws if missing
686
530
 
687
- ```typescript
688
- // sendLog works even without credentials (returns 'silent')
689
- const hiveLogger = new HiveLogClient({
690
- projectName: 'My Project'
691
- // No credentials provided - will use environment variables or go silent
692
- })
531
+ ### Silent Mode
693
532
 
694
- const status = await hiveLogger.sendLogByName('task-name', { data: 'example' })
695
- if (status === 'error') {
696
- console.error('Network or API error')
697
- } else if (status === 'silent') {
698
- console.log('Running in silent mode - no credentials')
699
- }
700
- ```
701
-
702
- ### Error Handling Patterns
533
+ When credentials are missing, the client runs in "silent mode":
703
534
 
704
- **Check credentials before API calls:**
705
535
  ```typescript
706
- const hiveLogger = new HiveLogClient({
707
- projectName: 'My Project'
708
- // Credentials will be loaded from environment variables or explicit config
709
- })
536
+ const client = createClientFromForgeConf('./forge.json')
537
+ // No credentials in env vars - will go silent
710
538
 
711
- if (hiveLogger.isActive()) {
712
- // Safe to use all methods
713
- const logData = await hiveLogger.getLog('task', 'uuid')
714
- await hiveLogger.setQuality('task', 'uuid', quality)
715
- } else {
716
- console.log('Running in silent mode')
539
+ const status = await client.sendLog(record)
540
+ if (status === 'silent') {
541
+ console.log('Running in silent mode - logs not sent')
717
542
  }
718
- ```
719
543
 
720
- **sendLogByName** - Returns status strings (never throws):
721
- ```typescript
722
- const status = await hiveLogger.sendLogByName('task', { data: 'test' })
723
- // Returns: 'success', 'error', or 'silent'
724
- ```
725
-
726
- **getLog and setQuality** - Throw errors when credentials missing:
727
- ```typescript
728
- try {
729
- await hiveLogger.getLog('task', 'uuid')
730
- await hiveLogger.setQuality('task', 'uuid', quality)
731
- } catch (error) {
732
- console.error('Missing credentials:', error.message)
544
+ // Check before calling methods that throw
545
+ if (client.isActive()) {
546
+ await client.getLog('task', 'uuid')
733
547
  }
734
548
  ```
735
549
 
736
- ## Examples
737
-
738
- ### Complete Example
550
+ ## Complete Example
739
551
 
740
552
  ```typescript
741
- import { HiveLogClient, isApiError, Quality, Metadata, LogItemInput } from '@forgehive/hive-sdk'
742
-
743
- async function main() {
744
- // Initialize the client with configuration object
745
- const hiveLogger = new HiveLogClient({
746
- projectName: 'Personal Knowledge Management System',
747
- apiKey: 'your_api_key_here',
748
- apiSecret: 'your_api_secret_here',
749
- host: 'https://your-hive-instance.com', // Optional, defaults to https://www.forgehive.cloud
750
- metadata: {
751
- environment: process.env.NODE_ENV || 'development',
752
- version: '1.0.0',
753
- service: 'document-search-service'
754
- }
755
- })
553
+ import { createClientFromForgeConf, Quality } from '@forgehive/hive-sdk'
554
+ import { Task } from '@forgehive/task'
555
+ import { getPrice } from './tasks/stock/getPrice'
756
556
 
757
- // Send a log with logItem containing metadata
758
- const logData = {
759
- input: { query: 'search for AI papers', userId: 123 },
760
- output: { results: ['paper1.pdf', 'paper2.pdf'], count: 2 },
761
- metadata: {
762
- searchAlgorithm: 'semantic-search-v2',
763
- processingTime: '245', // ms
764
- cacheHit: 'false'
765
- },
766
- boundaries: {
767
- search_engine: [
768
- {
769
- input: 'AI papers filetype:pdf',
770
- output: { hits: 150, results: ['...'] },
771
- error: null
772
- }
773
- ]
774
- }
557
+ // Create client from forge.json
558
+ const client = createClientFromForgeConf('./forge.json', {
559
+ metadata: {
560
+ environment: process.env.NODE_ENV || 'development',
561
+ version: '1.0.0'
775
562
  }
563
+ })
776
564
 
777
- // Send log with additional high-priority metadata
778
- const status = await hiveLogger.sendLogByName('document-search', logData, {
779
- requestId: 'req-123456',
780
- userId: 'user-789',
781
- sessionId: 'sess-abc123'
565
+ // Test configuration
566
+ const configTest = await client.testConfig()
567
+ if (!configTest.success) {
568
+ console.error('Config error:', configTest.error)
569
+ process.exit(1)
570
+ }
571
+
572
+ console.log('Connected as:', configTest.userName)
573
+ console.log('Team:', configTest.teamName)
574
+ console.log('Project:', configTest.projectName)
575
+
576
+ // Option 1: Manual logging
577
+ const [result, error, record] = await getPrice.safeRun({ ticker: 'AAPL' })
578
+
579
+ if (error) {
580
+ console.error('Task failed:', error)
581
+ } else {
582
+ console.log('Result:', result)
583
+
584
+ // Send log manually
585
+ const status = await client.sendLog(record, {
586
+ requestId: 'req-123',
587
+ userId: 'user-456'
782
588
  })
783
- console.log('Log status:', status)
784
-
785
- // Retrieve a log
786
- try {
787
- const retrievedLog = await hiveLogger.getLog('document-search', 'some-uuid')
788
- if (retrievedLog && !isApiError(retrievedLog)) {
789
- console.log('Retrieved log:', retrievedLog.logItem)
790
- console.log('Log metadata:', retrievedLog.logItem.metadata)
791
-
792
- // Set quality assessment
793
- const quality: Quality = {
794
- score: 9.0,
795
- reason: 'Excellent search results with high relevance',
796
- suggestions: 'Consider adding result ranking by publication date'
797
- }
798
-
799
- const qualitySet = await hiveLogger.setQuality('document-search', retrievedLog.uuid, quality)
800
- console.log('Quality assessment saved:', qualitySet)
801
- }
802
- } catch (error) {
803
- console.error('Missing credentials for getLog/setQuality:', error.message)
804
- }
589
+ console.log('Log sent:', status)
805
590
  }
806
591
 
807
- main().catch(console.error)
592
+ // Option 2: Automatic logging with global listener
593
+ Task.listenExecutionRecords(client.getListener())
594
+
595
+ // All subsequent task executions are automatically logged
596
+ await getPrice.safeRun({ ticker: 'GOOGL' }) // Automatically logged
597
+ await getPrice.safeRun({ ticker: 'MSFT' }) // Automatically logged
808
598
  ```
809
599
 
810
600
  ## License