@forgehive/hive-sdk 0.0.1 → 0.0.3
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 +335 -19
- package/dist/index.d.ts +27 -3
- package/dist/index.js +36 -15
- package/dist/test/getLog.test.js +8 -12
- package/dist/test/index.test.js +13 -13
- package/dist/test/metadata.test.d.ts +1 -0
- package/dist/test/metadata.test.js +352 -0
- package/dist/test/sendLog.test.js +15 -19
- package/dist/test/setQuality.test.js +10 -17
- package/package.json +1 -1
- package/src/index.ts +154 -15
- package/src/test/getLog.test.ts +9 -15
- package/src/test/index.test.ts +13 -13
- package/src/test/metadata.test.ts +467 -0
- package/src/test/sendLog.test.ts +16 -22
- package/src/test/setQuality.test.ts +11 -21
package/README.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
A TypeScript/JavaScript SDK for interacting with the Forge Hive logging and quality assessment platform.
|
|
4
4
|
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
Create a client with:
|
|
8
|
+
```typescript
|
|
9
|
+
import { HiveLogClient } from '@forgehive/hive-sdk'
|
|
10
|
+
|
|
11
|
+
// Create client with explicit configuration (recommended)
|
|
12
|
+
const client = new HiveLogClient({
|
|
13
|
+
projectName: 'My Project',
|
|
14
|
+
apiKey: 'your_api_key',
|
|
15
|
+
apiSecret: 'your_api_secret'
|
|
16
|
+
})
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
On your app
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// Run a task
|
|
23
|
+
const [res, error, record] = await someTask.safeRun(args)
|
|
24
|
+
|
|
25
|
+
// Send a log
|
|
26
|
+
await client.sendLog('task-name', record)
|
|
27
|
+
```
|
|
28
|
+
|
|
5
29
|
## Installation
|
|
6
30
|
|
|
7
31
|
```bash
|
|
@@ -16,34 +40,154 @@ pnpm add @forgehive/hive-sdk
|
|
|
16
40
|
|
|
17
41
|
## Setup
|
|
18
42
|
|
|
19
|
-
### 1.
|
|
43
|
+
### 1. Configuration Options
|
|
20
44
|
|
|
21
|
-
|
|
45
|
+
The Hive SDK can be configured in two ways:
|
|
46
|
+
|
|
47
|
+
#### Option A: Explicit Configuration (Recommended)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { HiveLogClient, createHiveLogClient } from '@forgehive/hive-sdk'
|
|
51
|
+
|
|
52
|
+
// Direct configuration with credentials
|
|
53
|
+
const config = {
|
|
54
|
+
projectName: 'My Project',
|
|
55
|
+
apiKey: 'your_api_key_here',
|
|
56
|
+
apiSecret: 'your_api_secret_here',
|
|
57
|
+
host: 'https://your-hive-instance.com', // Optional, defaults to https://www.forgehive.cloud
|
|
58
|
+
metadata: { // Optional base metadata
|
|
59
|
+
environment: 'production',
|
|
60
|
+
version: '1.2.0'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const hiveLogger = new HiveLogClient(config)
|
|
65
|
+
// or using the factory function
|
|
66
|
+
const hiveLogger2 = createHiveLogClient(config)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Option B: Environment Variables (Fallback)
|
|
70
|
+
|
|
71
|
+
If you prefer environment variables, the SDK will automatically use them when no explicit credentials are provided:
|
|
22
72
|
|
|
23
73
|
```bash
|
|
24
74
|
HIVE_API_KEY=your_api_key_here
|
|
25
75
|
HIVE_API_SECRET=your_api_secret_here
|
|
26
|
-
HIVE_HOST=https://your-hive-instance.com
|
|
76
|
+
HIVE_HOST=https://your-hive-instance.com # Optional, defaults to https://www.forgehive.cloud
|
|
27
77
|
```
|
|
28
78
|
|
|
29
|
-
|
|
79
|
+
```typescript
|
|
80
|
+
import { HiveLogClient } from '@forgehive/hive-sdk'
|
|
81
|
+
|
|
82
|
+
// Uses environment variables for credentials
|
|
83
|
+
const hiveLogger = new HiveLogClient({
|
|
84
|
+
projectName: 'My Project',
|
|
85
|
+
metadata: {
|
|
86
|
+
environment: 'production',
|
|
87
|
+
version: '1.2.0'
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
You can get your API credentials at [https://www.forgehive.cloud](https://www.forgehive.cloud).
|
|
30
93
|
|
|
31
94
|
### 2. Basic Usage
|
|
32
95
|
|
|
33
96
|
```typescript
|
|
34
|
-
import { createHiveLogClient } from '@forgehive/hive-sdk'
|
|
97
|
+
import { HiveLogClient, createHiveLogClient } from '@forgehive/hive-sdk'
|
|
98
|
+
|
|
99
|
+
// Create client with explicit config
|
|
100
|
+
const hiveLogger = new HiveLogClient({
|
|
101
|
+
projectName: 'Personal Knowledge Management System',
|
|
102
|
+
apiKey: 'your_api_key',
|
|
103
|
+
apiSecret: 'your_api_secret',
|
|
104
|
+
metadata: {
|
|
105
|
+
environment: 'production',
|
|
106
|
+
version: '1.2.0',
|
|
107
|
+
team: 'backend'
|
|
108
|
+
}
|
|
109
|
+
})
|
|
35
110
|
|
|
36
|
-
|
|
111
|
+
// Or using factory function
|
|
112
|
+
const hiveLogger2 = createHiveLogClient({
|
|
113
|
+
projectName: 'Personal Knowledge Management System',
|
|
114
|
+
metadata: {
|
|
115
|
+
environment: 'production',
|
|
116
|
+
version: '1.2.0',
|
|
117
|
+
team: 'backend'
|
|
118
|
+
}
|
|
119
|
+
})
|
|
37
120
|
```
|
|
38
121
|
|
|
39
122
|
## API Methods
|
|
40
123
|
|
|
124
|
+
### `new HiveLogClient(config: HiveLogClientConfig): HiveLogClient`
|
|
125
|
+
|
|
126
|
+
Creates a new Hive log client instance with configuration object.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { HiveLogClient, HiveLogClientConfig, Metadata } from '@forgehive/hive-sdk'
|
|
130
|
+
|
|
131
|
+
// Minimal configuration (uses environment variables for credentials)
|
|
132
|
+
const client = new HiveLogClient({
|
|
133
|
+
projectName: 'My Project'
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// Full configuration with explicit credentials
|
|
137
|
+
const config: HiveLogClientConfig = {
|
|
138
|
+
projectName: 'My Project',
|
|
139
|
+
apiKey: 'your_api_key',
|
|
140
|
+
apiSecret: 'your_api_secret',
|
|
141
|
+
host: 'https://your-hive-instance.com', // Optional, defaults to https://www.forgehive.cloud
|
|
142
|
+
metadata: {
|
|
143
|
+
environment: 'production',
|
|
144
|
+
version: '2.1.0',
|
|
145
|
+
datacenter: 'us-east-1'
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const clientWithConfig = new HiveLogClient(config)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Configuration Object:**
|
|
152
|
+
- `projectName`: Name of your project (required)
|
|
153
|
+
- `apiKey`: API key (optional, falls back to `HIVE_API_KEY` environment variable)
|
|
154
|
+
- `apiSecret`: API secret (optional, falls back to `HIVE_API_SECRET` environment variable)
|
|
155
|
+
- `host`: Hive instance URL (optional, falls back to `HIVE_HOST` environment variable, then defaults to `https://www.forgehive.cloud`)
|
|
156
|
+
- `metadata`: Base metadata that will be included with every log (optional)
|
|
157
|
+
|
|
158
|
+
**Returns:** `HiveLogClient` - Configured client instance
|
|
159
|
+
|
|
160
|
+
### `createHiveLogClient(config: HiveLogClientConfig): HiveLogClient`
|
|
161
|
+
|
|
162
|
+
Factory function that creates a new Hive log client instance.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { createHiveLogClient } from '@forgehive/hive-sdk'
|
|
166
|
+
|
|
167
|
+
const client = createHiveLogClient({
|
|
168
|
+
projectName: 'My Project',
|
|
169
|
+
apiKey: 'your_api_key',
|
|
170
|
+
apiSecret: 'your_api_secret',
|
|
171
|
+
metadata: {
|
|
172
|
+
environment: 'production',
|
|
173
|
+
team: 'backend'
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Parameters:** Same as `HiveLogClient` constructor
|
|
179
|
+
**Returns:** `HiveLogClient` - Configured client instance
|
|
180
|
+
|
|
41
181
|
### `isActive(): boolean`
|
|
42
182
|
|
|
43
183
|
Check if the client is properly initialized with credentials.
|
|
44
184
|
|
|
45
185
|
```typescript
|
|
46
|
-
const hiveLogger =
|
|
186
|
+
const hiveLogger = new HiveLogClient({
|
|
187
|
+
projectName: 'My Project',
|
|
188
|
+
apiKey: 'your_api_key',
|
|
189
|
+
apiSecret: 'your_api_secret'
|
|
190
|
+
})
|
|
47
191
|
|
|
48
192
|
if (hiveLogger.isActive()) {
|
|
49
193
|
console.log('Client is initialized with credentials')
|
|
@@ -56,11 +200,12 @@ if (hiveLogger.isActive()) {
|
|
|
56
200
|
|
|
57
201
|
**Returns:** `boolean` - `true` if credentials are available, `false` if in silent mode
|
|
58
202
|
|
|
59
|
-
### `sendLog(taskName: string, logItem:
|
|
203
|
+
### `sendLog(taskName: string, logItem: LogItemInput, metadata?: Metadata): Promise<'success' | 'error' | 'silent'>`
|
|
60
204
|
|
|
61
|
-
Sends a log entry to Hive for a specific task.
|
|
205
|
+
Sends a log entry to Hive for a specific task with optional metadata. Accepts both manual log items and task execution records.
|
|
62
206
|
|
|
63
207
|
```typescript
|
|
208
|
+
// Using a manual log item
|
|
64
209
|
const status = await hiveLogger.sendLog('user-authentication', {
|
|
65
210
|
input: { username: 'john_doe', timestamp: Date.now() },
|
|
66
211
|
output: { success: true, userId: 12345 },
|
|
@@ -73,6 +218,16 @@ const status = await hiveLogger.sendLog('user-authentication', {
|
|
|
73
218
|
}
|
|
74
219
|
]
|
|
75
220
|
}
|
|
221
|
+
}, {
|
|
222
|
+
// This metadata has highest priority
|
|
223
|
+
requestId: 'req-123',
|
|
224
|
+
userId: 'user-456'
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
// Using a task execution record directly
|
|
228
|
+
const [result, error, record] = await someTask.safeRun(args)
|
|
229
|
+
await hiveLogger.sendLog('task-name', record, {
|
|
230
|
+
environment: 'production'
|
|
76
231
|
})
|
|
77
232
|
|
|
78
233
|
switch (status) {
|
|
@@ -90,7 +245,8 @@ switch (status) {
|
|
|
90
245
|
|
|
91
246
|
**Parameters:**
|
|
92
247
|
- `taskName`: Name of the task being logged
|
|
93
|
-
- `logItem`:
|
|
248
|
+
- `logItem`: LogItemInput object (supports both manual log items and task execution records)
|
|
249
|
+
- `metadata` (optional): Additional metadata for this specific log
|
|
94
250
|
|
|
95
251
|
**Returns:** `Promise<'success' | 'error' | 'silent'>` - Status of the operation
|
|
96
252
|
|
|
@@ -104,6 +260,7 @@ try {
|
|
|
104
260
|
|
|
105
261
|
if (logData && !isApiError(logData)) {
|
|
106
262
|
console.log('Log retrieved:', logData.logItem)
|
|
263
|
+
console.log('Log metadata:', logData.logItem.metadata)
|
|
107
264
|
} else if (logData && isApiError(logData)) {
|
|
108
265
|
console.error('API Error:', logData.error)
|
|
109
266
|
} else {
|
|
@@ -155,8 +312,139 @@ try {
|
|
|
155
312
|
**Returns:** `Promise<boolean>` - `true` if successful, `false` if failed
|
|
156
313
|
**Throws:** Error when credentials are missing
|
|
157
314
|
|
|
315
|
+
## Metadata System
|
|
316
|
+
|
|
317
|
+
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.
|
|
318
|
+
|
|
319
|
+
### Metadata Priority System
|
|
320
|
+
|
|
321
|
+
Metadata is merged using the following priority order (highest to lowest):
|
|
322
|
+
|
|
323
|
+
1. **sendLog metadata** - Metadata passed directly to the `sendLog` method
|
|
324
|
+
2. **logItem metadata** - Metadata already present in the `logItem` object
|
|
325
|
+
3. **Client base metadata** - Metadata set when creating the client
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
// Create client with base metadata
|
|
329
|
+
const client = new HiveLogClient({
|
|
330
|
+
projectName: 'My Project',
|
|
331
|
+
apiKey: 'your_api_key',
|
|
332
|
+
apiSecret: 'your_api_secret',
|
|
333
|
+
metadata: {
|
|
334
|
+
environment: 'production',
|
|
335
|
+
version: '1.0.0',
|
|
336
|
+
team: 'backend'
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
// logItem with metadata
|
|
341
|
+
const logItem = {
|
|
342
|
+
input: 'test input',
|
|
343
|
+
output: 'test output',
|
|
344
|
+
metadata: {
|
|
345
|
+
sessionId: 'session-123',
|
|
346
|
+
version: '1.1.0' // This overrides client version
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Send log with additional metadata
|
|
351
|
+
await client.sendLog('task-name', logItem, {
|
|
352
|
+
requestId: 'req-456',
|
|
353
|
+
version: '1.2.0' // This overrides both logItem and client version
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
// Final metadata sent will be:
|
|
357
|
+
// {
|
|
358
|
+
// environment: 'production', // from client
|
|
359
|
+
// team: 'backend', // from client
|
|
360
|
+
// sessionId: 'session-123', // from logItem
|
|
361
|
+
// version: '1.2.0', // from sendLog (highest priority)
|
|
362
|
+
// requestId: 'req-456' // from sendLog
|
|
363
|
+
// }
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Metadata Usage Examples
|
|
367
|
+
|
|
368
|
+
**Base metadata for all logs:**
|
|
369
|
+
```typescript
|
|
370
|
+
const client = new HiveLogClient({
|
|
371
|
+
projectName: 'My Service',
|
|
372
|
+
apiKey: 'your_api_key',
|
|
373
|
+
apiSecret: 'your_api_secret',
|
|
374
|
+
metadata: {
|
|
375
|
+
environment: process.env.NODE_ENV,
|
|
376
|
+
version: process.env.APP_VERSION,
|
|
377
|
+
datacenter: 'us-west-2'
|
|
378
|
+
}
|
|
379
|
+
})
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Request-specific metadata:**
|
|
383
|
+
```typescript
|
|
384
|
+
app.post('/api/users', async (req, res) => {
|
|
385
|
+
const result = await client.sendLog('create-user', {
|
|
386
|
+
input: req.body,
|
|
387
|
+
output: newUser
|
|
388
|
+
}, {
|
|
389
|
+
requestId: req.headers['x-request-id'],
|
|
390
|
+
userId: req.user?.id,
|
|
391
|
+
ipAddress: req.ip
|
|
392
|
+
})
|
|
393
|
+
})
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**logItem with embedded metadata:**
|
|
397
|
+
```typescript
|
|
398
|
+
const logItem = {
|
|
399
|
+
input: { query: 'search term' },
|
|
400
|
+
output: { results: [...] },
|
|
401
|
+
metadata: {
|
|
402
|
+
searchDuration: '245', // ms
|
|
403
|
+
resultCount: '15',
|
|
404
|
+
algorithm: 'fuzzy-v2'
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
await client.sendLog('search', logItem)
|
|
409
|
+
```
|
|
410
|
+
|
|
158
411
|
## Types
|
|
159
412
|
|
|
413
|
+
### `HiveLogClientConfig`
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
interface HiveLogClientConfig {
|
|
417
|
+
projectName: string
|
|
418
|
+
apiKey?: string
|
|
419
|
+
apiSecret?: string
|
|
420
|
+
host?: string
|
|
421
|
+
metadata?: Metadata
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### `LogItemInput` (also exported as `LogItem`)
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
interface LogItemInput {
|
|
429
|
+
input: unknown
|
|
430
|
+
output?: unknown
|
|
431
|
+
error?: unknown
|
|
432
|
+
boundaries?: unknown // Flexible to accept different boundary structures
|
|
433
|
+
metadata?: Metadata
|
|
434
|
+
taskName?: string
|
|
435
|
+
type?: string
|
|
436
|
+
[key: string]: unknown // Allows task execution records and other additional properties
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### `Metadata`
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
interface Metadata {
|
|
444
|
+
[key: string]: string
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
160
448
|
### `LogApiResponse`
|
|
161
449
|
|
|
162
450
|
```typescript
|
|
@@ -169,6 +457,7 @@ interface LogApiResponse {
|
|
|
169
457
|
output?: unknown
|
|
170
458
|
error?: unknown
|
|
171
459
|
boundaries?: Record<string, Array<{ input: unknown; output: unknown, error: unknown }>>
|
|
460
|
+
metadata?: Metadata
|
|
172
461
|
}
|
|
173
462
|
replayFrom?: string
|
|
174
463
|
createdAt: string
|
|
@@ -237,7 +526,7 @@ hive-sdk Success: Sent log for task "user-authentication" +250ms
|
|
|
237
526
|
|
|
238
527
|
# Silent mode (missing credentials)
|
|
239
528
|
hive-sdk Creating HiveLogClient for project "Personal Knowledge Management System" +0ms
|
|
240
|
-
hive-sdk HiveLogClient in silent mode for project "Personal Knowledge Management System" - missing credentials (get them at https://forgehive.
|
|
529
|
+
hive-sdk HiveLogClient in silent mode for project "Personal Knowledge Management System" - missing credentials (get them at https://www.forgehive.cloud) +2ms
|
|
241
530
|
hive-sdk Silent mode: Skipping sendLog for task "user-authentication" - client not initialized +100ms
|
|
242
531
|
hive-sdk Error: getLog for task "user-task" with uuid "some-uuid" - missing credentials +150ms
|
|
243
532
|
|
|
@@ -258,7 +547,10 @@ The SDK handles errors gracefully:
|
|
|
258
547
|
|
|
259
548
|
```typescript
|
|
260
549
|
// sendLog works even without credentials (returns 'silent')
|
|
261
|
-
const hiveLogger =
|
|
550
|
+
const hiveLogger = new HiveLogClient({
|
|
551
|
+
projectName: 'My Project'
|
|
552
|
+
// No credentials provided - will use environment variables or go silent
|
|
553
|
+
})
|
|
262
554
|
|
|
263
555
|
const status = await hiveLogger.sendLog('task-name', { data: 'example' })
|
|
264
556
|
if (status === 'error') {
|
|
@@ -272,7 +564,10 @@ if (status === 'error') {
|
|
|
272
564
|
|
|
273
565
|
**Check credentials before API calls:**
|
|
274
566
|
```typescript
|
|
275
|
-
const hiveLogger =
|
|
567
|
+
const hiveLogger = new HiveLogClient({
|
|
568
|
+
projectName: 'My Project'
|
|
569
|
+
// Credentials will be loaded from environment variables or explicit config
|
|
570
|
+
})
|
|
276
571
|
|
|
277
572
|
if (hiveLogger.isActive()) {
|
|
278
573
|
// Safe to use all methods
|
|
@@ -304,16 +599,31 @@ try {
|
|
|
304
599
|
### Complete Example
|
|
305
600
|
|
|
306
601
|
```typescript
|
|
307
|
-
import {
|
|
602
|
+
import { HiveLogClient, isApiError, Quality, Metadata, LogItemInput } from '@forgehive/hive-sdk'
|
|
308
603
|
|
|
309
604
|
async function main() {
|
|
310
|
-
// Initialize the client
|
|
311
|
-
const hiveLogger =
|
|
605
|
+
// Initialize the client with configuration object
|
|
606
|
+
const hiveLogger = new HiveLogClient({
|
|
607
|
+
projectName: 'Personal Knowledge Management System',
|
|
608
|
+
apiKey: 'your_api_key_here',
|
|
609
|
+
apiSecret: 'your_api_secret_here',
|
|
610
|
+
host: 'https://your-hive-instance.com', // Optional, defaults to https://www.forgehive.cloud
|
|
611
|
+
metadata: {
|
|
612
|
+
environment: process.env.NODE_ENV || 'development',
|
|
613
|
+
version: '1.0.0',
|
|
614
|
+
service: 'document-search-service'
|
|
615
|
+
}
|
|
616
|
+
})
|
|
312
617
|
|
|
313
|
-
// Send a log
|
|
618
|
+
// Send a log with logItem containing metadata
|
|
314
619
|
const logData = {
|
|
315
620
|
input: { query: 'search for AI papers', userId: 123 },
|
|
316
621
|
output: { results: ['paper1.pdf', 'paper2.pdf'], count: 2 },
|
|
622
|
+
metadata: {
|
|
623
|
+
searchAlgorithm: 'semantic-search-v2',
|
|
624
|
+
processingTime: '245', // ms
|
|
625
|
+
cacheHit: 'false'
|
|
626
|
+
},
|
|
317
627
|
boundaries: {
|
|
318
628
|
search_engine: [
|
|
319
629
|
{
|
|
@@ -325,7 +635,12 @@ async function main() {
|
|
|
325
635
|
}
|
|
326
636
|
}
|
|
327
637
|
|
|
328
|
-
|
|
638
|
+
// Send log with additional high-priority metadata
|
|
639
|
+
const status = await hiveLogger.sendLog('document-search', logData, {
|
|
640
|
+
requestId: 'req-123456',
|
|
641
|
+
userId: 'user-789',
|
|
642
|
+
sessionId: 'sess-abc123'
|
|
643
|
+
})
|
|
329
644
|
console.log('Log status:', status)
|
|
330
645
|
|
|
331
646
|
// Retrieve a log
|
|
@@ -333,6 +648,7 @@ async function main() {
|
|
|
333
648
|
const retrievedLog = await hiveLogger.getLog('document-search', 'some-uuid')
|
|
334
649
|
if (retrievedLog && !isApiError(retrievedLog)) {
|
|
335
650
|
console.log('Retrieved log:', retrievedLog.logItem)
|
|
651
|
+
console.log('Log metadata:', retrievedLog.logItem.metadata)
|
|
336
652
|
|
|
337
653
|
// Set quality assessment
|
|
338
654
|
const quality: Quality = {
|
|
@@ -354,4 +670,4 @@ main().catch(console.error)
|
|
|
354
670
|
|
|
355
671
|
## License
|
|
356
672
|
|
|
357
|
-
ISC
|
|
673
|
+
ISC
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
export interface Metadata {
|
|
2
|
+
[key: string]: string;
|
|
3
|
+
}
|
|
4
|
+
export interface LogItemInput {
|
|
5
|
+
input: unknown;
|
|
6
|
+
output?: unknown;
|
|
7
|
+
error?: unknown;
|
|
8
|
+
boundaries?: unknown;
|
|
9
|
+
metadata?: Metadata;
|
|
10
|
+
}
|
|
11
|
+
export type LogItem = LogItemInput;
|
|
12
|
+
export interface HiveLogClientConfig {
|
|
13
|
+
projectName: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
apiSecret?: string;
|
|
16
|
+
host?: string;
|
|
17
|
+
metadata?: Metadata;
|
|
18
|
+
}
|
|
1
19
|
export interface LogApiResponse {
|
|
2
20
|
uuid: string;
|
|
3
21
|
taskName: string;
|
|
@@ -11,6 +29,7 @@ export interface LogApiResponse {
|
|
|
11
29
|
output: unknown;
|
|
12
30
|
error: unknown;
|
|
13
31
|
}>>;
|
|
32
|
+
metadata?: Metadata;
|
|
14
33
|
};
|
|
15
34
|
replayFrom?: string;
|
|
16
35
|
createdAt: string;
|
|
@@ -32,11 +51,16 @@ export declare class HiveLogClient {
|
|
|
32
51
|
private apiSecret;
|
|
33
52
|
private host;
|
|
34
53
|
private projectName;
|
|
54
|
+
private baseMetadata;
|
|
35
55
|
private isInitialized;
|
|
36
|
-
constructor(
|
|
56
|
+
constructor(config: HiveLogClientConfig);
|
|
37
57
|
isActive(): boolean;
|
|
38
|
-
|
|
58
|
+
private mergeMetadata;
|
|
59
|
+
sendLog<T extends {
|
|
60
|
+
input: unknown;
|
|
61
|
+
metadata?: Metadata;
|
|
62
|
+
}>(taskName: string, logItem: T, metadata?: Metadata): Promise<'success' | 'error' | 'silent'>;
|
|
39
63
|
getLog(taskName: string, uuid: string): Promise<LogApiResult | null>;
|
|
40
64
|
setQuality(taskName: string, uuid: string, quality: Quality): Promise<boolean>;
|
|
41
65
|
}
|
|
42
|
-
export declare const createHiveLogClient: (
|
|
66
|
+
export declare const createHiveLogClient: (config: HiveLogClientConfig) => HiveLogClient;
|
package/dist/index.js
CHANGED
|
@@ -13,30 +13,44 @@ function isApiError(response) {
|
|
|
13
13
|
return response !== null && typeof response === 'object' && 'error' in response;
|
|
14
14
|
}
|
|
15
15
|
class HiveLogClient {
|
|
16
|
-
constructor(
|
|
17
|
-
const apiKey = process.env.HIVE_API_KEY;
|
|
18
|
-
const apiSecret = process.env.HIVE_API_SECRET;
|
|
19
|
-
const host = process.env.HIVE_HOST;
|
|
20
|
-
this.projectName = projectName;
|
|
21
|
-
|
|
16
|
+
constructor(config) {
|
|
17
|
+
const apiKey = config.apiKey || process.env.HIVE_API_KEY;
|
|
18
|
+
const apiSecret = config.apiSecret || process.env.HIVE_API_SECRET;
|
|
19
|
+
const host = config.host || process.env.HIVE_HOST || 'https://www.forgehive.cloud';
|
|
20
|
+
this.projectName = config.projectName;
|
|
21
|
+
this.baseMetadata = config.metadata || {};
|
|
22
|
+
if (!apiKey || !apiSecret) {
|
|
22
23
|
this.apiKey = null;
|
|
23
24
|
this.apiSecret = null;
|
|
24
25
|
this.host = null;
|
|
25
26
|
this.isInitialized = false;
|
|
26
|
-
log('HiveLogClient in silent mode for project "%s" - missing credentials (get them at https://forgehive.
|
|
27
|
+
log('HiveLogClient in silent mode for project "%s" - missing API credentials (get them at https://www.forgehive.cloud)', config.projectName);
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
29
30
|
this.apiKey = apiKey;
|
|
30
31
|
this.apiSecret = apiSecret;
|
|
31
32
|
this.host = host;
|
|
32
33
|
this.isInitialized = true;
|
|
33
|
-
log('HiveLogClient initialized for project "%s" with host "%s"', projectName, host);
|
|
34
|
+
log('HiveLogClient initialized for project "%s" with host "%s"', config.projectName, host);
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
isActive() {
|
|
37
38
|
return this.isInitialized;
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
+
mergeMetadata(logItem, sendLogMetadata) {
|
|
41
|
+
// Start with base metadata from client
|
|
42
|
+
let finalMetadata = { ...this.baseMetadata };
|
|
43
|
+
// Merge with logItem metadata if it exists
|
|
44
|
+
if (logItem.metadata) {
|
|
45
|
+
finalMetadata = { ...finalMetadata, ...logItem.metadata };
|
|
46
|
+
}
|
|
47
|
+
// Merge with sendLog metadata (highest priority)
|
|
48
|
+
if (sendLogMetadata) {
|
|
49
|
+
finalMetadata = { ...finalMetadata, ...sendLogMetadata };
|
|
50
|
+
}
|
|
51
|
+
return finalMetadata;
|
|
52
|
+
}
|
|
53
|
+
async sendLog(taskName, logItem, metadata) {
|
|
40
54
|
if (!this.isInitialized) {
|
|
41
55
|
log('Silent mode: Skipping sendLog for task "%s" - client not initialized', taskName);
|
|
42
56
|
return 'silent';
|
|
@@ -45,10 +59,17 @@ class HiveLogClient {
|
|
|
45
59
|
const logsUrl = `${this.host}/api/tasks/log-ingest`;
|
|
46
60
|
log('Sending log for task "%s" to %s', taskName, logsUrl);
|
|
47
61
|
const authToken = `${this.apiKey}:${this.apiSecret}`;
|
|
62
|
+
// Merge metadata with priority: sendLog > logItem > client
|
|
63
|
+
const finalMetadata = this.mergeMetadata(logItem, metadata);
|
|
64
|
+
// Create enhanced logItem with merged metadata
|
|
65
|
+
const enhancedLogItem = {
|
|
66
|
+
...logItem,
|
|
67
|
+
metadata: finalMetadata
|
|
68
|
+
};
|
|
48
69
|
await axios_1.default.post(logsUrl, {
|
|
49
70
|
projectName: this.projectName,
|
|
50
71
|
taskName,
|
|
51
|
-
logItem: JSON.stringify(
|
|
72
|
+
logItem: JSON.stringify(enhancedLogItem)
|
|
52
73
|
}, {
|
|
53
74
|
headers: {
|
|
54
75
|
Authorization: `Bearer ${authToken}`,
|
|
@@ -67,7 +88,7 @@ class HiveLogClient {
|
|
|
67
88
|
async getLog(taskName, uuid) {
|
|
68
89
|
if (!this.isInitialized) {
|
|
69
90
|
log('Error: getLog for task "%s" with uuid "%s" - missing credentials', taskName, uuid);
|
|
70
|
-
throw new Error('Missing Hive API credentials or host, get them at https://forgehive.
|
|
91
|
+
throw new Error('Missing Hive API credentials or host, get them at https://www.forgehive.cloud');
|
|
71
92
|
}
|
|
72
93
|
try {
|
|
73
94
|
const logUrl = `${this.host}/api/tasks/${taskName}/logs/${uuid}`;
|
|
@@ -91,7 +112,7 @@ class HiveLogClient {
|
|
|
91
112
|
async setQuality(taskName, uuid, quality) {
|
|
92
113
|
if (!this.isInitialized) {
|
|
93
114
|
log('Error: setQuality for task "%s" with uuid "%s" - missing credentials', taskName, uuid);
|
|
94
|
-
throw new Error('Missing Hive API credentials or host, get them at https://forgehive.
|
|
115
|
+
throw new Error('Missing Hive API credentials or host, get them at https://www.forgehive.cloud');
|
|
95
116
|
}
|
|
96
117
|
try {
|
|
97
118
|
const qualityUrl = `${this.host}/api/tasks/${taskName}/logs/${uuid}/set-quality`;
|
|
@@ -116,8 +137,8 @@ class HiveLogClient {
|
|
|
116
137
|
}
|
|
117
138
|
}
|
|
118
139
|
exports.HiveLogClient = HiveLogClient;
|
|
119
|
-
const createHiveLogClient = (
|
|
120
|
-
log('Creating HiveLogClient for project "%s"', projectName);
|
|
121
|
-
return new HiveLogClient(
|
|
140
|
+
const createHiveLogClient = (config) => {
|
|
141
|
+
log('Creating HiveLogClient for project "%s"', config.projectName);
|
|
142
|
+
return new HiveLogClient(config);
|
|
122
143
|
};
|
|
123
144
|
exports.createHiveLogClient = createHiveLogClient;
|
package/dist/test/getLog.test.js
CHANGED
|
@@ -9,23 +9,19 @@ const index_1 = require("../index");
|
|
|
9
9
|
jest.mock('axios');
|
|
10
10
|
const mockedAxios = axios_1.default;
|
|
11
11
|
describe('HiveLogClient getLog', () => {
|
|
12
|
-
const originalEnv = process.env;
|
|
13
12
|
let client;
|
|
13
|
+
const testConfig = {
|
|
14
|
+
projectName: 'test-project',
|
|
15
|
+
apiKey: 'test-api-key',
|
|
16
|
+
apiSecret: 'test-api-secret',
|
|
17
|
+
host: 'https://test-host.com'
|
|
18
|
+
};
|
|
14
19
|
beforeEach(() => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// Set up environment variables
|
|
18
|
-
process.env.HIVE_API_KEY = 'test-api-key';
|
|
19
|
-
process.env.HIVE_API_SECRET = 'test-api-secret';
|
|
20
|
-
process.env.HIVE_HOST = 'https://test-host.com';
|
|
21
|
-
// Create client instance
|
|
22
|
-
client = new index_1.HiveLogClient('test-project');
|
|
20
|
+
// Create client instance with config
|
|
21
|
+
client = new index_1.HiveLogClient(testConfig);
|
|
23
22
|
// Clear all mocks
|
|
24
23
|
jest.clearAllMocks();
|
|
25
24
|
});
|
|
26
|
-
afterAll(() => {
|
|
27
|
-
process.env = originalEnv;
|
|
28
|
-
});
|
|
29
25
|
describe('successful getLog', () => {
|
|
30
26
|
it('should fetch log successfully and return LogApiResponse', async () => {
|
|
31
27
|
const mockLogResponse = {
|