@thinkhive/sdk 3.3.0 → 4.0.1
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/MIGRATION.md +83 -12
- package/README.md +24 -12
- package/dist/api/agents.d.ts +169 -0
- package/dist/api/agents.js +185 -0
- package/dist/api/apiKeys.js +5 -5
- package/dist/api/calibration.d.ts +0 -62
- package/dist/api/calibration.js +5 -48
- package/dist/api/claims.js +10 -7
- package/dist/api/conversation-eval.js +4 -4
- package/dist/api/deterministic-graders.js +5 -5
- package/dist/api/eval-health.js +9 -9
- package/dist/api/human-review.js +16 -16
- package/dist/api/nondeterminism.js +11 -11
- package/dist/api/roi-analytics.js +2 -2
- package/dist/api/runs.js +12 -6
- package/dist/api/transcript-patterns.js +5 -5
- package/dist/core/client.d.ts +2 -2
- package/dist/core/client.js +8 -4
- package/dist/core/config.d.ts +2 -3
- package/dist/core/config.js +3 -4
- package/dist/core/types.d.ts +30 -2
- package/dist/core/types.js +1 -1
- package/dist/index.d.ts +15 -15
- package/dist/index.js +13 -9
- package/package.json +2 -2
package/MIGRATION.md
CHANGED
|
@@ -1,6 +1,86 @@
|
|
|
1
|
-
# Migration Guide
|
|
1
|
+
# Migration Guide
|
|
2
2
|
|
|
3
|
-
This guide
|
|
3
|
+
This guide covers migration between major versions of the ThinkHive SDK.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## v3.x to v4.0
|
|
8
|
+
|
|
9
|
+
### Breaking Changes
|
|
10
|
+
|
|
11
|
+
#### `apiVersion` Removed from `InitOptions`
|
|
12
|
+
|
|
13
|
+
The `apiVersion` configuration option has been removed. The SDK now handles API routing internally -- modules automatically route to the correct API version.
|
|
14
|
+
|
|
15
|
+
```diff
|
|
16
|
+
init({
|
|
17
|
+
apiKey: 'th_xxx',
|
|
18
|
+
serviceName: 'my-agent',
|
|
19
|
+
- apiVersion: 'v3',
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
#### Default Endpoint Changed
|
|
24
|
+
|
|
25
|
+
The default endpoint is now `https://app.thinkhive.ai` (previously pointed to the staging Cloud Run URL).
|
|
26
|
+
|
|
27
|
+
```diff
|
|
28
|
+
// If you were relying on the old default, no action needed —
|
|
29
|
+
// the new default points to production.
|
|
30
|
+
// If you explicitly set the old staging URL, remove it:
|
|
31
|
+
init({
|
|
32
|
+
apiKey: 'th_xxx',
|
|
33
|
+
serviceName: 'my-agent',
|
|
34
|
+
- endpoint: 'https://thinkhivemind-h25z7pvd3q-uc.a.run.app',
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### Calibration API Changes
|
|
39
|
+
|
|
40
|
+
`calibration.recordOutcome()` and `calibration.reliabilityDiagram()` have been removed. Use `calibration.status()` to check calibration state.
|
|
41
|
+
|
|
42
|
+
```diff
|
|
43
|
+
- await calibration.recordOutcome({
|
|
44
|
+
- runId: run.id,
|
|
45
|
+
- predictionType: 'churn_risk',
|
|
46
|
+
- predictedValue: 0.7,
|
|
47
|
+
- actualOutcome: 1,
|
|
48
|
+
- });
|
|
49
|
+
-
|
|
50
|
+
- const diagram = await calibration.reliabilityDiagram(agentId);
|
|
51
|
+
|
|
52
|
+
// Still available:
|
|
53
|
+
const status = await calibration.status(agentId, 'churn_risk');
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### OTLP Init Requires API Key
|
|
57
|
+
|
|
58
|
+
Initializing the SDK with only an `agentId` is no longer sufficient for OTLP-based tracing. You must provide an `apiKey`.
|
|
59
|
+
|
|
60
|
+
```diff
|
|
61
|
+
init({
|
|
62
|
+
+ apiKey: 'th_xxx',
|
|
63
|
+
agentId: 'agent-123',
|
|
64
|
+
serviceName: 'my-agent',
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Version Bump
|
|
69
|
+
|
|
70
|
+
The SDK version is now `4.0.0`. Update your `package.json`:
|
|
71
|
+
|
|
72
|
+
```diff
|
|
73
|
+
"dependencies": {
|
|
74
|
+
- "@thinkhive/sdk": "^3.3.0"
|
|
75
|
+
+ "@thinkhive/sdk": "^4.0.0"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## v2.x to v3.0
|
|
82
|
+
|
|
83
|
+
This section covers migration from ThinkHive SDK v2.x to v3.0.
|
|
4
84
|
|
|
5
85
|
## Breaking Changes
|
|
6
86
|
|
|
@@ -48,13 +128,12 @@ init({
|
|
|
48
128
|
serviceName: 'my-agent',
|
|
49
129
|
});
|
|
50
130
|
|
|
51
|
-
// v3
|
|
131
|
+
// v3+
|
|
52
132
|
import { init } from '@thinkhive/sdk';
|
|
53
133
|
|
|
54
134
|
init({
|
|
55
135
|
apiKey: 'th_xxx',
|
|
56
136
|
serviceName: 'my-agent',
|
|
57
|
-
apiVersion: 'v3', // Default is v3
|
|
58
137
|
});
|
|
59
138
|
```
|
|
60
139
|
|
|
@@ -196,14 +275,6 @@ import { calibration } from '@thinkhive/sdk';
|
|
|
196
275
|
const status = await calibration.status('agent_123', 'churn_risk');
|
|
197
276
|
console.log(`Brier score: ${status.brierScore}`);
|
|
198
277
|
console.log(`Is calibrated: ${status.isCalibrated}`);
|
|
199
|
-
|
|
200
|
-
// Record prediction outcomes
|
|
201
|
-
await calibration.recordOutcome({
|
|
202
|
-
runId: run.id,
|
|
203
|
-
predictionType: 'churn_risk',
|
|
204
|
-
predictedValue: 0.7, // We predicted 70% churn risk
|
|
205
|
-
actualOutcome: 1, // Customer did churn
|
|
206
|
-
});
|
|
207
278
|
```
|
|
208
279
|
|
|
209
280
|
## Deprecated APIs
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ThinkHive SDK
|
|
1
|
+
# ThinkHive SDK v4.0.0
|
|
2
2
|
|
|
3
3
|
The official JavaScript/TypeScript SDK for [ThinkHive](https://thinkhive.ai) - AI Agent Observability Platform.
|
|
4
4
|
|
|
@@ -27,7 +27,7 @@ import { init, runs, traceLLM, shutdown } from '@thinkhive/sdk';
|
|
|
27
27
|
|
|
28
28
|
// Initialize the SDK
|
|
29
29
|
init({
|
|
30
|
-
apiKey: '
|
|
30
|
+
apiKey: 'thk_your_api_key',
|
|
31
31
|
serviceName: 'my-ai-agent',
|
|
32
32
|
autoInstrument: true,
|
|
33
33
|
frameworks: ['langchain', 'openai'],
|
|
@@ -36,7 +36,7 @@ init({
|
|
|
36
36
|
// Create a run (atomic unit of work)
|
|
37
37
|
const run = await runs.create({
|
|
38
38
|
agentId: 'weather-agent',
|
|
39
|
-
|
|
39
|
+
conversationMessages: [
|
|
40
40
|
{ role: 'user', content: 'What is the weather in San Francisco?' },
|
|
41
41
|
{ role: 'assistant', content: 'The weather in San Francisco is currently 65°F and sunny.' }
|
|
42
42
|
],
|
|
@@ -54,7 +54,7 @@ await shutdown();
|
|
|
54
54
|
```typescript
|
|
55
55
|
import { init, traceLLM, traceRetrieval, traceTool, traceChain } from '@thinkhive/sdk';
|
|
56
56
|
|
|
57
|
-
init({ apiKey: '
|
|
57
|
+
init({ apiKey: 'thk_your_api_key', serviceName: 'my-agent' });
|
|
58
58
|
|
|
59
59
|
// Trace an LLM call
|
|
60
60
|
const response = await traceLLM({
|
|
@@ -194,14 +194,17 @@ const confident = getHighConfidenceClaims(claimList, 0.9);
|
|
|
194
194
|
```typescript
|
|
195
195
|
import { calibration, calculateBrierScore, isWellCalibrated } from '@thinkhive/sdk';
|
|
196
196
|
|
|
197
|
-
// Get calibration status
|
|
198
|
-
const status = await calibration.
|
|
197
|
+
// Get calibration status for a prediction type
|
|
198
|
+
const status = await calibration.status(agentId, 'churn_risk');
|
|
199
|
+
|
|
200
|
+
// Get all calibration metrics
|
|
201
|
+
const metrics = await calibration.allMetrics(agentId);
|
|
199
202
|
|
|
200
203
|
// Calculate Brier score for predictions
|
|
201
|
-
const brierScore = calculateBrierScore(predictions
|
|
204
|
+
const brierScore = calculateBrierScore(predictions);
|
|
202
205
|
|
|
203
206
|
// Check if well calibrated
|
|
204
|
-
if (isWellCalibrated(
|
|
207
|
+
if (isWellCalibrated(brierScore)) {
|
|
205
208
|
console.log('Agent predictions are well calibrated');
|
|
206
209
|
}
|
|
207
210
|
```
|
|
@@ -284,7 +287,7 @@ import { init } from '@thinkhive/sdk';
|
|
|
284
287
|
|
|
285
288
|
// Initialize with auto-instrumentation
|
|
286
289
|
init({
|
|
287
|
-
apiKey: '
|
|
290
|
+
apiKey: 'thk_your_api_key',
|
|
288
291
|
serviceName: 'my-ai-agent',
|
|
289
292
|
autoInstrument: true,
|
|
290
293
|
frameworks: ['langchain', 'openai', 'anthropic']
|
|
@@ -306,10 +309,10 @@ init({
|
|
|
306
309
|
| Variable | Description |
|
|
307
310
|
|----------|-------------|
|
|
308
311
|
| `THINKHIVE_API_KEY` | Your ThinkHive API key |
|
|
309
|
-
| `THINKHIVE_ENDPOINT` | Custom API endpoint (default: https://
|
|
312
|
+
| `THINKHIVE_ENDPOINT` | Custom API endpoint (default: https://app.thinkhive.ai) |
|
|
310
313
|
| `THINKHIVE_SERVICE_NAME` | Service name for traces (optional) |
|
|
311
314
|
|
|
312
|
-
##
|
|
315
|
+
## Architecture
|
|
313
316
|
|
|
314
317
|
### Key Concepts
|
|
315
318
|
|
|
@@ -344,7 +347,7 @@ init({
|
|
|
344
347
|
| `roiAnalytics` | Business ROI and financial impact analysis |
|
|
345
348
|
| `qualityMetrics` | RAG evaluation and hallucination detection |
|
|
346
349
|
|
|
347
|
-
###
|
|
350
|
+
### Evaluation APIs
|
|
348
351
|
|
|
349
352
|
| API | Description |
|
|
350
353
|
|-----|-------------|
|
|
@@ -355,6 +358,15 @@ init({
|
|
|
355
358
|
| `conversationEval` | Multi-turn conversation evaluation |
|
|
356
359
|
| `transcriptPatterns` | Pattern detection in transcripts |
|
|
357
360
|
|
|
361
|
+
## Upgrading from v3
|
|
362
|
+
|
|
363
|
+
See [MIGRATION.md](MIGRATION.md) for the full v3 → v4 migration guide. Key changes:
|
|
364
|
+
|
|
365
|
+
- **`apiVersion` removed** from `init()` options — routing is handled automatically per module
|
|
366
|
+
- **`calibration.recordOutcome()`** and **`calibration.reliabilityDiagram()`** removed — use `calibration.status()` and `calibration.allMetrics()` instead
|
|
367
|
+
- **Default endpoint** changed from staging to `https://app.thinkhive.ai`
|
|
368
|
+
- **OTLP init** now requires `apiKey` (agent ID alone is not sufficient)
|
|
369
|
+
|
|
358
370
|
## API Reference
|
|
359
371
|
|
|
360
372
|
See [API Documentation](https://docs.thinkhive.ai/sdk/javascript/reference) for complete type definitions.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThinkHive SDK - Agents Management
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for managing AI agents:
|
|
5
|
+
* - List, get, create, update, delete agents
|
|
6
|
+
* - Agent configuration management
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { agents } from 'thinkhive-js';
|
|
11
|
+
*
|
|
12
|
+
* // List all agents
|
|
13
|
+
* const allAgents = await agents.list();
|
|
14
|
+
*
|
|
15
|
+
* // Create a new agent
|
|
16
|
+
* const agent = await agents.create({
|
|
17
|
+
* name: 'Support Agent',
|
|
18
|
+
* description: 'Handles customer support',
|
|
19
|
+
* agentType: 'customer_support',
|
|
20
|
+
* primarySuccessMetric: 'Deflection Rate',
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Update an agent
|
|
24
|
+
* await agents.update(agent.id, { name: 'Updated Agent' });
|
|
25
|
+
*
|
|
26
|
+
* // Get agent configuration
|
|
27
|
+
* const config = await agents.getConfig(agent.id);
|
|
28
|
+
*
|
|
29
|
+
* // Delete an agent (with dry-run preview)
|
|
30
|
+
* const impact = await agents.delete(agent.id, { dryRun: true });
|
|
31
|
+
* console.log(`Will delete ${impact.cascadeImpact.traces} traces`);
|
|
32
|
+
*
|
|
33
|
+
* // Actually delete
|
|
34
|
+
* await agents.delete(agent.id);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export interface Agent {
|
|
38
|
+
id: string;
|
|
39
|
+
companyId: string;
|
|
40
|
+
departmentId?: string | null;
|
|
41
|
+
createdBy?: string | null;
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
industry: string;
|
|
45
|
+
successMetrics: string[];
|
|
46
|
+
agentType?: string | null;
|
|
47
|
+
agentOwner?: string | null;
|
|
48
|
+
builtInHouse?: boolean | null;
|
|
49
|
+
primarySuccessMetric?: string | null;
|
|
50
|
+
secondaryMetrics?: string[] | null;
|
|
51
|
+
connectedSystem?: string | null;
|
|
52
|
+
telemetryMethod?: string | null;
|
|
53
|
+
autoEvaluate?: boolean | null;
|
|
54
|
+
evaluationSampleRate?: string | null;
|
|
55
|
+
defaultCriteriaIds?: string[] | null;
|
|
56
|
+
defaultGuardrailIds?: string[] | null;
|
|
57
|
+
createdAt?: string | null;
|
|
58
|
+
}
|
|
59
|
+
export interface CreateAgentOptions {
|
|
60
|
+
name: string;
|
|
61
|
+
description?: string;
|
|
62
|
+
industry?: string;
|
|
63
|
+
agentType?: string;
|
|
64
|
+
agentOwner?: string;
|
|
65
|
+
builtInHouse?: boolean;
|
|
66
|
+
departmentId?: string;
|
|
67
|
+
successMetrics?: string[];
|
|
68
|
+
primarySuccessMetric?: string;
|
|
69
|
+
secondaryMetrics?: string[];
|
|
70
|
+
connectedSystem?: string;
|
|
71
|
+
autoEvaluate?: boolean;
|
|
72
|
+
evaluationSampleRate?: number;
|
|
73
|
+
}
|
|
74
|
+
export interface UpdateAgentOptions {
|
|
75
|
+
name?: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
agentType?: string;
|
|
78
|
+
agentOwner?: string;
|
|
79
|
+
builtInHouse?: boolean;
|
|
80
|
+
departmentId?: string | null;
|
|
81
|
+
industry?: string;
|
|
82
|
+
primarySuccessMetric?: string;
|
|
83
|
+
secondaryMetrics?: string[];
|
|
84
|
+
connectedSystem?: string;
|
|
85
|
+
autoEvaluate?: boolean;
|
|
86
|
+
evaluationSampleRate?: number;
|
|
87
|
+
isActive?: boolean;
|
|
88
|
+
}
|
|
89
|
+
export interface AgentConfig {
|
|
90
|
+
id: string;
|
|
91
|
+
agentId: string;
|
|
92
|
+
version: number;
|
|
93
|
+
name: string;
|
|
94
|
+
description?: string | null;
|
|
95
|
+
provider: string;
|
|
96
|
+
model: string;
|
|
97
|
+
temperature?: string | null;
|
|
98
|
+
maxTokens?: number | null;
|
|
99
|
+
systemPrompt?: string | null;
|
|
100
|
+
promptTemplate?: string | null;
|
|
101
|
+
ragEnabled?: boolean | null;
|
|
102
|
+
ragConfig?: unknown;
|
|
103
|
+
toolsEnabled?: boolean | null;
|
|
104
|
+
tools?: unknown;
|
|
105
|
+
isBaseline?: boolean | null;
|
|
106
|
+
isActive?: boolean | null;
|
|
107
|
+
createdAt?: string | null;
|
|
108
|
+
updatedAt?: string | null;
|
|
109
|
+
}
|
|
110
|
+
export interface UpdateAgentConfigOptions {
|
|
111
|
+
name?: string;
|
|
112
|
+
provider?: string;
|
|
113
|
+
model?: string;
|
|
114
|
+
temperature?: number;
|
|
115
|
+
maxTokens?: number;
|
|
116
|
+
systemPrompt?: string;
|
|
117
|
+
promptTemplate?: string;
|
|
118
|
+
ragEnabled?: boolean;
|
|
119
|
+
ragConfig?: Record<string, unknown>;
|
|
120
|
+
toolsEnabled?: boolean;
|
|
121
|
+
tools?: unknown[];
|
|
122
|
+
}
|
|
123
|
+
export interface DeleteAgentOptions {
|
|
124
|
+
/** If true, returns cascade impact without actually deleting */
|
|
125
|
+
dryRun?: boolean;
|
|
126
|
+
}
|
|
127
|
+
export interface CascadeImpact {
|
|
128
|
+
dryRun: boolean;
|
|
129
|
+
agentId: string;
|
|
130
|
+
agentName: string;
|
|
131
|
+
cascadeImpact: {
|
|
132
|
+
traces: number;
|
|
133
|
+
apiKeys: number;
|
|
134
|
+
runningEvaluations?: number;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export declare const agents: {
|
|
138
|
+
/**
|
|
139
|
+
* List agents for the authenticated company
|
|
140
|
+
*/
|
|
141
|
+
list(options?: {
|
|
142
|
+
companyId?: string;
|
|
143
|
+
departmentId?: string;
|
|
144
|
+
}): Promise<Agent[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Get a single agent by ID
|
|
147
|
+
*/
|
|
148
|
+
get(id: string): Promise<Agent>;
|
|
149
|
+
/**
|
|
150
|
+
* Create a new agent
|
|
151
|
+
*/
|
|
152
|
+
create(options: CreateAgentOptions): Promise<Agent>;
|
|
153
|
+
/**
|
|
154
|
+
* Update an existing agent
|
|
155
|
+
*/
|
|
156
|
+
update(id: string, options: UpdateAgentOptions): Promise<Agent>;
|
|
157
|
+
/**
|
|
158
|
+
* Delete an agent. Use dryRun option to preview cascade impact.
|
|
159
|
+
*/
|
|
160
|
+
delete(id: string, options?: DeleteAgentOptions): Promise<void | CascadeImpact>;
|
|
161
|
+
/**
|
|
162
|
+
* Get agent configuration (baseline)
|
|
163
|
+
*/
|
|
164
|
+
getConfig(agentId: string): Promise<AgentConfig | null>;
|
|
165
|
+
/**
|
|
166
|
+
* Create or update agent configuration
|
|
167
|
+
*/
|
|
168
|
+
updateConfig(agentId: string, config: UpdateAgentConfigOptions): Promise<AgentConfig>;
|
|
169
|
+
};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ThinkHive SDK - Agents Management
|
|
4
|
+
*
|
|
5
|
+
* CRUD operations for managing AI agents:
|
|
6
|
+
* - List, get, create, update, delete agents
|
|
7
|
+
* - Agent configuration management
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { agents } from 'thinkhive-js';
|
|
12
|
+
*
|
|
13
|
+
* // List all agents
|
|
14
|
+
* const allAgents = await agents.list();
|
|
15
|
+
*
|
|
16
|
+
* // Create a new agent
|
|
17
|
+
* const agent = await agents.create({
|
|
18
|
+
* name: 'Support Agent',
|
|
19
|
+
* description: 'Handles customer support',
|
|
20
|
+
* agentType: 'customer_support',
|
|
21
|
+
* primarySuccessMetric: 'Deflection Rate',
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Update an agent
|
|
25
|
+
* await agents.update(agent.id, { name: 'Updated Agent' });
|
|
26
|
+
*
|
|
27
|
+
* // Get agent configuration
|
|
28
|
+
* const config = await agents.getConfig(agent.id);
|
|
29
|
+
*
|
|
30
|
+
* // Delete an agent (with dry-run preview)
|
|
31
|
+
* const impact = await agents.delete(agent.id, { dryRun: true });
|
|
32
|
+
* console.log(`Will delete ${impact.cascadeImpact.traces} traces`);
|
|
33
|
+
*
|
|
34
|
+
* // Actually delete
|
|
35
|
+
* await agents.delete(agent.id);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.agents = void 0;
|
|
40
|
+
const client_1 = require("../core/client");
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// API Client
|
|
43
|
+
// ============================================================================
|
|
44
|
+
exports.agents = {
|
|
45
|
+
/**
|
|
46
|
+
* List agents for the authenticated company
|
|
47
|
+
*/
|
|
48
|
+
async list(options) {
|
|
49
|
+
const params = new URLSearchParams();
|
|
50
|
+
if (options?.companyId)
|
|
51
|
+
params.set('companyId', options.companyId);
|
|
52
|
+
if (options?.departmentId)
|
|
53
|
+
params.set('departmentId', options.departmentId);
|
|
54
|
+
const qs = params.toString();
|
|
55
|
+
const response = await (0, client_1.apiRequest)(`/agents${qs ? `?${qs}` : ''}`, { apiVersion: 'none' });
|
|
56
|
+
return response.data ?? response;
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* Get a single agent by ID
|
|
60
|
+
*/
|
|
61
|
+
async get(id) {
|
|
62
|
+
if (!id)
|
|
63
|
+
throw new client_1.ThinkHiveValidationError('Agent ID is required', 'id');
|
|
64
|
+
const response = await (0, client_1.apiRequest)(`/agents/${id}`, { apiVersion: 'none' });
|
|
65
|
+
return response.data ?? response;
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* Create a new agent
|
|
69
|
+
*/
|
|
70
|
+
async create(options) {
|
|
71
|
+
if (!options.name) {
|
|
72
|
+
throw new client_1.ThinkHiveValidationError('Agent name is required', 'name');
|
|
73
|
+
}
|
|
74
|
+
const body = {
|
|
75
|
+
name: options.name,
|
|
76
|
+
description: options.description || '',
|
|
77
|
+
industry: options.industry || 'other',
|
|
78
|
+
successMetrics: options.successMetrics ?? [options.primarySuccessMetric || 'Task Success Rate'],
|
|
79
|
+
};
|
|
80
|
+
if (options.agentType)
|
|
81
|
+
body.agentType = options.agentType;
|
|
82
|
+
if (options.agentOwner)
|
|
83
|
+
body.agentOwner = options.agentOwner;
|
|
84
|
+
if (options.builtInHouse !== undefined)
|
|
85
|
+
body.builtInHouse = options.builtInHouse;
|
|
86
|
+
if (options.departmentId)
|
|
87
|
+
body.departmentId = options.departmentId;
|
|
88
|
+
if (options.primarySuccessMetric)
|
|
89
|
+
body.primarySuccessMetric = options.primarySuccessMetric;
|
|
90
|
+
if (options.secondaryMetrics)
|
|
91
|
+
body.secondaryMetrics = options.secondaryMetrics;
|
|
92
|
+
if (options.connectedSystem)
|
|
93
|
+
body.connectedSystem = options.connectedSystem;
|
|
94
|
+
if (options.autoEvaluate !== undefined)
|
|
95
|
+
body.autoEvaluate = options.autoEvaluate;
|
|
96
|
+
if (options.evaluationSampleRate !== undefined) {
|
|
97
|
+
body.evaluationSampleRate = options.evaluationSampleRate.toFixed(4);
|
|
98
|
+
}
|
|
99
|
+
const response = await (0, client_1.apiRequest)('/agents', {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
body,
|
|
102
|
+
apiVersion: 'none',
|
|
103
|
+
});
|
|
104
|
+
return response.data ?? response;
|
|
105
|
+
},
|
|
106
|
+
/**
|
|
107
|
+
* Update an existing agent
|
|
108
|
+
*/
|
|
109
|
+
async update(id, options) {
|
|
110
|
+
if (!id)
|
|
111
|
+
throw new client_1.ThinkHiveValidationError('Agent ID is required', 'id');
|
|
112
|
+
const body = {};
|
|
113
|
+
if (options.name !== undefined)
|
|
114
|
+
body.name = options.name;
|
|
115
|
+
if (options.description !== undefined)
|
|
116
|
+
body.description = options.description;
|
|
117
|
+
if (options.agentType !== undefined)
|
|
118
|
+
body.agentType = options.agentType;
|
|
119
|
+
if (options.agentOwner !== undefined)
|
|
120
|
+
body.agentOwner = options.agentOwner;
|
|
121
|
+
if (options.builtInHouse !== undefined)
|
|
122
|
+
body.builtInHouse = options.builtInHouse;
|
|
123
|
+
if (options.departmentId !== undefined)
|
|
124
|
+
body.departmentId = options.departmentId;
|
|
125
|
+
if (options.industry !== undefined)
|
|
126
|
+
body.industry = options.industry;
|
|
127
|
+
if (options.primarySuccessMetric !== undefined)
|
|
128
|
+
body.primarySuccessMetric = options.primarySuccessMetric;
|
|
129
|
+
if (options.secondaryMetrics !== undefined)
|
|
130
|
+
body.secondaryMetrics = options.secondaryMetrics;
|
|
131
|
+
if (options.connectedSystem !== undefined)
|
|
132
|
+
body.connectedSystem = options.connectedSystem;
|
|
133
|
+
if (options.autoEvaluate !== undefined)
|
|
134
|
+
body.autoEvaluate = options.autoEvaluate;
|
|
135
|
+
if (options.isActive !== undefined)
|
|
136
|
+
body.isActive = options.isActive;
|
|
137
|
+
if (options.evaluationSampleRate !== undefined) {
|
|
138
|
+
body.evaluationSampleRate = options.evaluationSampleRate.toFixed(4);
|
|
139
|
+
}
|
|
140
|
+
const response = await (0, client_1.apiRequest)(`/agents/${id}`, {
|
|
141
|
+
method: 'PATCH',
|
|
142
|
+
body,
|
|
143
|
+
apiVersion: 'none',
|
|
144
|
+
});
|
|
145
|
+
return response.data ?? response;
|
|
146
|
+
},
|
|
147
|
+
/**
|
|
148
|
+
* Delete an agent. Use dryRun option to preview cascade impact.
|
|
149
|
+
*/
|
|
150
|
+
async delete(id, options) {
|
|
151
|
+
if (!id)
|
|
152
|
+
throw new client_1.ThinkHiveValidationError('Agent ID is required', 'id');
|
|
153
|
+
const qs = options?.dryRun ? '?dryRun=true' : '';
|
|
154
|
+
const response = await (0, client_1.apiRequest)(`/agents/${id}${qs}`, {
|
|
155
|
+
method: 'DELETE',
|
|
156
|
+
apiVersion: 'none',
|
|
157
|
+
});
|
|
158
|
+
if (options?.dryRun) {
|
|
159
|
+
return response.data ?? response;
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
/**
|
|
163
|
+
* Get agent configuration (baseline)
|
|
164
|
+
*/
|
|
165
|
+
async getConfig(agentId) {
|
|
166
|
+
if (!agentId)
|
|
167
|
+
throw new client_1.ThinkHiveValidationError('Agent ID is required', 'agentId');
|
|
168
|
+
const response = await (0, client_1.apiRequest)(`/agents/${agentId}/config`, { apiVersion: 'none' });
|
|
169
|
+
return response?.data ?? response ?? null;
|
|
170
|
+
},
|
|
171
|
+
/**
|
|
172
|
+
* Create or update agent configuration
|
|
173
|
+
*/
|
|
174
|
+
async updateConfig(agentId, config) {
|
|
175
|
+
if (!agentId)
|
|
176
|
+
throw new client_1.ThinkHiveValidationError('Agent ID is required', 'agentId');
|
|
177
|
+
const response = await (0, client_1.apiRequest)(`/agents/${agentId}/config`, {
|
|
178
|
+
method: 'PUT',
|
|
179
|
+
body: config,
|
|
180
|
+
apiVersion: 'none',
|
|
181
|
+
});
|
|
182
|
+
return response.data ?? response;
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9hZ2VudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1DRzs7O0FBRUgsMkNBQXNFO0FBaUh0RSwrRUFBK0U7QUFDL0UsYUFBYTtBQUNiLCtFQUErRTtBQUVsRSxRQUFBLE1BQU0sR0FBRztJQUNwQjs7T0FFRztJQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsT0FHVjtRQUNDLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFDckMsSUFBSSxPQUFPLEVBQUUsU0FBUztZQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuRSxJQUFJLE9BQU8sRUFBRSxZQUFZO1lBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRTVFLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM3QixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUEsbUJBQVUsRUFBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMxRixPQUFRLFFBQWdCLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQVU7UUFDbEIsSUFBSSxDQUFDLEVBQUU7WUFBRSxNQUFNLElBQUksaUNBQXdCLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUUsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFBLG1CQUFVLEVBQUMsV0FBVyxFQUFFLEVBQUUs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QyxPQUFPO1lBQUUsTUFBTSxJQUFJLGlDQUF3QixDQUFDLHNCQUFzQixFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRXBGLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSxtQkFBVSxFQUFDLFdBQVcsT0FBTyxTQUFTLEVBQUU7WUFDN0QsTUFBTSxFQUFFLEtBQUs7WUFDYixJQUFJLEVBQUUsTUFBTTtZQUNaLFVBQVUsRUFBRSxNQUFNO1NBQ25CLENBQUMsQ0FBQztRQUNILE9BQVEsUUFBZ0IsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDO0lBQzVDLENBQUM7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGlua0hpdmUgU0RLIC0gQWdlbnRzIE1hbmFnZW1lbnRcbiAqXG4gKiBDUlVEIG9wZXJhdGlvbnMgZm9yIG1hbmFnaW5nIEFJIGFnZW50czpcbiAqIC0gTGlzdCwgZ2V0LCBjcmVhdGUsIHVwZGF0ZSwgZGVsZXRlIGFnZW50c1xuICogLSBBZ2VudCBjb25maWd1cmF0aW9uIG1hbmFnZW1lbnRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgYWdlbnRzIH0gZnJvbSAndGhpbmtoaXZlLWpzJztcbiAqXG4gKiAvLyBMaXN0IGFsbCBhZ2VudHNcbiAqIGNvbnN0IGFsbEFnZW50cyA9IGF3YWl0IGFnZW50cy5saXN0KCk7XG4gKlxuICogLy8gQ3JlYXRlIGEgbmV3IGFnZW50XG4gKiBjb25zdCBhZ2VudCA9IGF3YWl0IGFnZW50cy5jcmVhdGUoe1xuICogICBuYW1lOiAnU3VwcG9ydCBBZ2VudCcsXG4gKiAgIGRlc2NyaXB0aW9uOiAnSGFuZGxlcyBjdXN0b21lciBzdXBwb3J0JyxcbiAqICAgYWdlbnRUeXBlOiAnY3VzdG9tZXJfc3VwcG9ydCcsXG4gKiAgIHByaW1hcnlTdWNjZXNzTWV0cmljOiAnRGVmbGVjdGlvbiBSYXRlJyxcbiAqIH0pO1xuICpcbiAqIC8vIFVwZGF0ZSBhbiBhZ2VudFxuICogYXdhaXQgYWdlbnRzLnVwZGF0ZShhZ2VudC5pZCwgeyBuYW1lOiAnVXBkYXRlZCBBZ2VudCcgfSk7XG4gKlxuICogLy8gR2V0IGFnZW50IGNvbmZpZ3VyYXRpb25cbiAqIGNvbnN0IGNvbmZpZyA9IGF3YWl0IGFnZW50cy5nZXRDb25maWcoYWdlbnQuaWQpO1xuICpcbiAqIC8vIERlbGV0ZSBhbiBhZ2VudCAod2l0aCBkcnktcnVuIHByZXZpZXcpXG4gKiBjb25zdCBpbXBhY3QgPSBhd2FpdCBhZ2VudHMuZGVsZXRlKGFnZW50LmlkLCB7IGRyeVJ1bjogdHJ1ZSB9KTtcbiAqIGNvbnNvbGUubG9nKGBXaWxsIGRlbGV0ZSAke2ltcGFjdC5jYXNjYWRlSW1wYWN0LnRyYWNlc30gdHJhY2VzYCk7XG4gKlxuICogLy8gQWN0dWFsbHkgZGVsZXRlXG4gKiBhd2FpdCBhZ2VudHMuZGVsZXRlKGFnZW50LmlkKTtcbiAqIGBgYFxuICovXG5cbmltcG9ydCB7IGFwaVJlcXVlc3QsIFRoaW5rSGl2ZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJy4uL2NvcmUvY2xpZW50JztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBBZ2VudCB7XG4gIGlkOiBzdHJpbmc7XG4gIGNvbXBhbnlJZDogc3RyaW5nO1xuICBkZXBhcnRtZW50SWQ/OiBzdHJpbmcgfCBudWxsO1xuICBjcmVhdGVkQnk/OiBzdHJpbmcgfCBudWxsO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGluZHVzdHJ5OiBzdHJpbmc7XG4gIHN1Y2Nlc3NNZXRyaWNzOiBzdHJpbmdbXTtcbiAgYWdlbnRUeXBlPzogc3RyaW5nIHwgbnVsbDtcbiAgYWdlbnRPd25lcj86IHN0cmluZyB8IG51bGw7XG4gIGJ1aWx0SW5Ib3VzZT86IGJvb2xlYW4gfCBudWxsO1xuICBwcmltYXJ5U3VjY2Vzc01ldHJpYz86IHN0cmluZyB8IG51bGw7XG4gIHNlY29uZGFyeU1ldHJpY3M/OiBzdHJpbmdbXSB8IG51bGw7XG4gIGNvbm5lY3RlZFN5c3RlbT86IHN0cmluZyB8IG51bGw7XG4gIHRlbGVtZXRyeU1ldGhvZD86IHN0cmluZyB8IG51bGw7XG4gIGF1dG9FdmFsdWF0ZT86IGJvb2xlYW4gfCBudWxsO1xuICBldmFsdWF0aW9uU2FtcGxlUmF0ZT86IHN0cmluZyB8IG51bGw7XG4gIGRlZmF1bHRDcml0ZXJpYUlkcz86IHN0cmluZ1tdIHwgbnVsbDtcbiAgZGVmYXVsdEd1YXJkcmFpbElkcz86IHN0cmluZ1tdIHwgbnVsbDtcbiAgY3JlYXRlZEF0Pzogc3RyaW5nIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVBZ2VudE9wdGlvbnMge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBpbmR1c3RyeT86IHN0cmluZztcbiAgYWdlbnRUeXBlPzogc3RyaW5nO1xuICBhZ2VudE93bmVyPzogc3RyaW5nO1xuICBidWlsdEluSG91c2U/OiBib29sZWFuO1xuICBkZXBhcnRtZW50SWQ/OiBzdHJpbmc7XG4gIHN1Y2Nlc3NNZXRyaWNzPzogc3RyaW5nW107XG4gIHByaW1hcnlTdWNjZXNzTWV0cmljPzogc3RyaW5nO1xuICBzZWNvbmRhcnlNZXRyaWNzPzogc3RyaW5nW107XG4gIGNvbm5lY3RlZFN5c3RlbT86IHN0cmluZztcbiAgYXV0b0V2YWx1YXRlPzogYm9vbGVhbjtcbiAgZXZhbHVhdGlvblNhbXBsZVJhdGU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBkYXRlQWdlbnRPcHRpb25zIHtcbiAgbmFtZT86IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIGFnZW50VHlwZT86IHN0cmluZztcbiAgYWdlbnRPd25lcj86IHN0cmluZztcbiAgYnVpbHRJbkhvdXNlPzogYm9vbGVhbjtcbiAgZGVwYXJ0bWVudElkPzogc3RyaW5nIHwgbnVsbDtcbiAgaW5kdXN0cnk/OiBzdHJpbmc7XG4gIHByaW1hcnlTdWNjZXNzTWV0cmljPzogc3RyaW5nO1xuICBzZWNvbmRhcnlNZXRyaWNzPzogc3RyaW5nW107XG4gIGNvbm5lY3RlZFN5c3RlbT86IHN0cmluZztcbiAgYXV0b0V2YWx1YXRlPzogYm9vbGVhbjtcbiAgZXZhbHVhdGlvblNhbXBsZVJhdGU/OiBudW1iZXI7XG4gIGlzQWN0aXZlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZ2VudENvbmZpZyB7XG4gIGlkOiBzdHJpbmc7XG4gIGFnZW50SWQ6IHN0cmluZztcbiAgdmVyc2lvbjogbnVtYmVyO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nIHwgbnVsbDtcbiAgcHJvdmlkZXI6IHN0cmluZztcbiAgbW9kZWw6IHN0cmluZztcbiAgdGVtcGVyYXR1cmU/OiBzdHJpbmcgfCBudWxsO1xuICBtYXhUb2tlbnM/OiBudW1iZXIgfCBudWxsO1xuICBzeXN0ZW1Qcm9tcHQ/OiBzdHJpbmcgfCBudWxsO1xuICBwcm9tcHRUZW1wbGF0ZT86IHN0cmluZyB8IG51bGw7XG4gIHJhZ0VuYWJsZWQ/OiBib29sZWFuIHwgbnVsbDtcbiAgcmFnQ29uZmlnPzogdW5rbm93bjtcbiAgdG9vbHNFbmFibGVkPzogYm9vbGVhbiB8IG51bGw7XG4gIHRvb2xzPzogdW5rbm93bjtcbiAgaXNCYXNlbGluZT86IGJvb2xlYW4gfCBudWxsO1xuICBpc0FjdGl2ZT86IGJvb2xlYW4gfCBudWxsO1xuICBjcmVhdGVkQXQ/OiBzdHJpbmcgfCBudWxsO1xuICB1cGRhdGVkQXQ/OiBzdHJpbmcgfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZUFnZW50Q29uZmlnT3B0aW9ucyB7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHByb3ZpZGVyPzogc3RyaW5nO1xuICBtb2RlbD86IHN0cmluZztcbiAgdGVtcGVyYXR1cmU/OiBudW1iZXI7XG4gIG1heFRva2Vucz86IG51bWJlcjtcbiAgc3lzdGVtUHJvbXB0Pzogc3RyaW5nO1xuICBwcm9tcHRUZW1wbGF0ZT86IHN0cmluZztcbiAgcmFnRW5hYmxlZD86IGJvb2xlYW47XG4gIHJhZ0NvbmZpZz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB0b29sc0VuYWJsZWQ/OiBib29sZWFuO1xuICB0b29scz86IHVua25vd25bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZWxldGVBZ2VudE9wdGlvbnMge1xuICAvKiogSWYgdHJ1ZSwgcmV0dXJucyBjYXNjYWRlIGltcGFjdCB3aXRob3V0IGFjdHVhbGx5IGRlbGV0aW5nICovXG4gIGRyeVJ1bj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FzY2FkZUltcGFjdCB7XG4gIGRyeVJ1bjogYm9vbGVhbjtcbiAgYWdlbnRJZDogc3RyaW5nO1xuICBhZ2VudE5hbWU6IHN0cmluZztcbiAgY2FzY2FkZUltcGFjdDoge1xuICAgIHRyYWNlczogbnVtYmVyO1xuICAgIGFwaUtleXM6IG51bWJlcjtcbiAgICBydW5uaW5nRXZhbHVhdGlvbnM/OiBudW1iZXI7XG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEFQSSBDbGllbnRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGNvbnN0IGFnZW50cyA9IHtcbiAgLyoqXG4gICAqIExpc3QgYWdlbnRzIGZvciB0aGUgYXV0aGVudGljYXRlZCBjb21wYW55XG4gICAqL1xuICBhc3luYyBsaXN0KG9wdGlvbnM/OiB7XG4gICAgY29tcGFueUlkPzogc3RyaW5nO1xuICAgIGRlcGFydG1lbnRJZD86IHN0cmluZztcbiAgfSk6IFByb21pc2U8QWdlbnRbXT4ge1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICBpZiAob3B0aW9ucz8uY29tcGFueUlkKSBwYXJhbXMuc2V0KCdjb21wYW55SWQnLCBvcHRpb25zLmNvbXBhbnlJZCk7XG4gICAgaWYgKG9wdGlvbnM/LmRlcGFydG1lbnRJZCkgcGFyYW1zLnNldCgnZGVwYXJ0bWVudElkJywgb3B0aW9ucy5kZXBhcnRtZW50SWQpO1xuXG4gICAgY29uc3QgcXMgPSBwYXJhbXMudG9TdHJpbmcoKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGFwaVJlcXVlc3QoYC9hZ2VudHMke3FzID8gYD8ke3FzfWAgOiAnJ31gLCB7IGFwaVZlcnNpb246ICdub25lJyB9KTtcbiAgICByZXR1cm4gKHJlc3BvbnNlIGFzIGFueSkuZGF0YSA/PyByZXNwb25zZTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGEgc2luZ2xlIGFnZW50IGJ5IElEXG4gICAqL1xuICBhc3luYyBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8QWdlbnQ+IHtcbiAgICBpZiAoIWlkKSB0aHJvdyBuZXcgVGhpbmtIaXZlVmFsaWRhdGlvbkVycm9yKCdBZ2VudCBJRCBpcyByZXF1aXJlZCcsICdpZCcpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXBpUmVxdWVzdChgL2FnZW50cy8ke2lkfWAsIHsgYXBpVmVyc2lvbjogJ25vbmUnIH0pO1xuICAgIHJldHVybiAocmVzcG9uc2UgYXMgYW55KS5kYXRhID8/IHJlc3BvbnNlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgYWdlbnRcbiAgICovXG4gIGFzeW5jIGNyZWF0ZShvcHRpb25zOiBDcmVhdGVBZ2VudE9wdGlvbnMpOiBQcm9taXNlPEFnZW50PiB7XG4gICAgaWYgKCFvcHRpb25zLm5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBUaGlua0hpdmVWYWxpZGF0aW9uRXJyb3IoJ0FnZW50IG5hbWUgaXMgcmVxdWlyZWQnLCAnbmFtZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGJvZHk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge1xuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZGVzY3JpcHRpb246IG9wdGlvbnMuZGVzY3JpcHRpb24gfHwgJycsXG4gICAgICBpbmR1c3RyeTogb3B0aW9ucy5pbmR1c3RyeSB8fCAnb3RoZXInLFxuICAgICAgc3VjY2Vzc01ldHJpY3M6IG9wdGlvbnMuc3VjY2Vzc01ldHJpY3MgPz8gW29wdGlvbnMucHJpbWFyeVN1Y2Nlc3NNZXRyaWMgfHwgJ1Rhc2sgU3VjY2VzcyBSYXRlJ10sXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLmFnZW50VHlwZSkgYm9keS5hZ2VudFR5cGUgPSBvcHRpb25zLmFnZW50VHlwZTtcbiAgICBpZiAob3B0aW9ucy5hZ2VudE93bmVyKSBib2R5LmFnZW50T3duZXIgPSBvcHRpb25zLmFnZW50T3duZXI7XG4gICAgaWYgKG9wdGlvbnMuYnVpbHRJbkhvdXNlICE9PSB1bmRlZmluZWQpIGJvZHkuYnVpbHRJbkhvdXNlID0gb3B0aW9ucy5idWlsdEluSG91c2U7XG4gICAgaWYgKG9wdGlvbnMuZGVwYXJ0bWVudElkKSBib2R5LmRlcGFydG1lbnRJZCA9IG9wdGlvbnMuZGVwYXJ0bWVudElkO1xuICAgIGlmIChvcHRpb25zLnByaW1hcnlTdWNjZXNzTWV0cmljKSBib2R5LnByaW1hcnlTdWNjZXNzTWV0cmljID0gb3B0aW9ucy5wcmltYXJ5U3VjY2Vzc01ldHJpYztcbiAgICBpZiAob3B0aW9ucy5zZWNvbmRhcnlNZXRyaWNzKSBib2R5LnNlY29uZGFyeU1ldHJpY3MgPSBvcHRpb25zLnNlY29uZGFyeU1ldHJpY3M7XG4gICAgaWYgKG9wdGlvbnMuY29ubmVjdGVkU3lzdGVtKSBib2R5LmNvbm5lY3RlZFN5c3RlbSA9IG9wdGlvbnMuY29ubmVjdGVkU3lzdGVtO1xuICAgIGlmIChvcHRpb25zLmF1dG9FdmFsdWF0ZSAhPT0gdW5kZWZpbmVkKSBib2R5LmF1dG9FdmFsdWF0ZSA9IG9wdGlvbnMuYXV0b0V2YWx1YXRlO1xuICAgIGlmIChvcHRpb25zLmV2YWx1YXRpb25TYW1wbGVSYXRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJvZHkuZXZhbHVhdGlvblNhbXBsZVJhdGUgPSBvcHRpb25zLmV2YWx1YXRpb25TYW1wbGVSYXRlLnRvRml4ZWQoNCk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBhcGlSZXF1ZXN0KCcvYWdlbnRzJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5LFxuICAgICAgYXBpVmVyc2lvbjogJ25vbmUnLFxuICAgIH0pO1xuICAgIHJldHVybiAocmVzcG9uc2UgYXMgYW55KS5kYXRhID8/IHJlc3BvbnNlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYW4gZXhpc3RpbmcgYWdlbnRcbiAgICovXG4gIGFzeW5jIHVwZGF0ZShpZDogc3RyaW5nLCBvcHRpb25zOiBVcGRhdGVBZ2VudE9wdGlvbnMpOiBQcm9taXNlPEFnZW50PiB7XG4gICAgaWYgKCFpZCkgdGhyb3cgbmV3IFRoaW5rSGl2ZVZhbGlkYXRpb25FcnJvcignQWdlbnQgSUQgaXMgcmVxdWlyZWQnLCAnaWQnKTtcblxuICAgIGNvbnN0IGJvZHk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgaWYgKG9wdGlvbnMubmFtZSAhPT0gdW5kZWZpbmVkKSBib2R5Lm5hbWUgPSBvcHRpb25zLm5hbWU7XG4gICAgaWYgKG9wdGlvbnMuZGVzY3JpcHRpb24gIT09IHVuZGVmaW5lZCkgYm9keS5kZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XG4gICAgaWYgKG9wdGlvbnMuYWdlbnRUeXBlICE9PSB1bmRlZmluZWQpIGJvZHkuYWdlbnRUeXBlID0gb3B0aW9ucy5hZ2VudFR5cGU7XG4gICAgaWYgKG9wdGlvbnMuYWdlbnRPd25lciAhPT0gdW5kZWZpbmVkKSBib2R5LmFnZW50T3duZXIgPSBvcHRpb25zLmFnZW50T3duZXI7XG4gICAgaWYgKG9wdGlvbnMuYnVpbHRJbkhvdXNlICE9PSB1bmRlZmluZWQpIGJvZHkuYnVpbHRJbkhvdXNlID0gb3B0aW9ucy5idWlsdEluSG91c2U7XG4gICAgaWYgKG9wdGlvbnMuZGVwYXJ0bWVudElkICE9PSB1bmRlZmluZWQpIGJvZHkuZGVwYXJ0bWVudElkID0gb3B0aW9ucy5kZXBhcnRtZW50SWQ7XG4gICAgaWYgKG9wdGlvbnMuaW5kdXN0cnkgIT09IHVuZGVmaW5lZCkgYm9keS5pbmR1c3RyeSA9IG9wdGlvbnMuaW5kdXN0cnk7XG4gICAgaWYgKG9wdGlvbnMucHJpbWFyeVN1Y2Nlc3NNZXRyaWMgIT09IHVuZGVmaW5lZCkgYm9keS5wcmltYXJ5U3VjY2Vzc01ldHJpYyA9IG9wdGlvbnMucHJpbWFyeVN1Y2Nlc3NNZXRyaWM7XG4gICAgaWYgKG9wdGlvbnMuc2Vjb25kYXJ5TWV0cmljcyAhPT0gdW5kZWZpbmVkKSBib2R5LnNlY29uZGFyeU1ldHJpY3MgPSBvcHRpb25zLnNlY29uZGFyeU1ldHJpY3M7XG4gICAgaWYgKG9wdGlvbnMuY29ubmVjdGVkU3lzdGVtICE9PSB1bmRlZmluZWQpIGJvZHkuY29ubmVjdGVkU3lzdGVtID0gb3B0aW9ucy5jb25uZWN0ZWRTeXN0ZW07XG4gICAgaWYgKG9wdGlvbnMuYXV0b0V2YWx1YXRlICE9PSB1bmRlZmluZWQpIGJvZHkuYXV0b0V2YWx1YXRlID0gb3B0aW9ucy5hdXRvRXZhbHVhdGU7XG4gICAgaWYgKG9wdGlvbnMuaXNBY3RpdmUgIT09IHVuZGVmaW5lZCkgYm9keS5pc0FjdGl2ZSA9IG9wdGlvbnMuaXNBY3RpdmU7XG4gICAgaWYgKG9wdGlvbnMuZXZhbHVhdGlvblNhbXBsZVJhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYm9keS5ldmFsdWF0aW9uU2FtcGxlUmF0ZSA9IG9wdGlvbnMuZXZhbHVhdGlvblNhbXBsZVJhdGUudG9GaXhlZCg0KTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGFwaVJlcXVlc3QoYC9hZ2VudHMvJHtpZH1gLCB7XG4gICAgICBtZXRob2Q6ICdQQVRDSCcsXG4gICAgICBib2R5LFxuICAgICAgYXBpVmVyc2lvbjogJ25vbmUnLFxuICAgIH0pO1xuICAgIHJldHVybiAocmVzcG9uc2UgYXMgYW55KS5kYXRhID8/IHJlc3BvbnNlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBEZWxldGUgYW4gYWdlbnQuIFVzZSBkcnlSdW4gb3B0aW9uIHRvIHByZXZpZXcgY2FzY2FkZSBpbXBhY3QuXG4gICAqL1xuICBhc3luYyBkZWxldGUoaWQ6IHN0cmluZywgb3B0aW9ucz86IERlbGV0ZUFnZW50T3B0aW9ucyk6IFByb21pc2U8dm9pZCB8IENhc2NhZGVJbXBhY3Q+IHtcbiAgICBpZiAoIWlkKSB0aHJvdyBuZXcgVGhpbmtIaXZlVmFsaWRhdGlvbkVycm9yKCdBZ2VudCBJRCBpcyByZXF1aXJlZCcsICdpZCcpO1xuXG4gICAgY29uc3QgcXMgPSBvcHRpb25zPy5kcnlSdW4gPyAnP2RyeVJ1bj10cnVlJyA6ICcnO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXBpUmVxdWVzdChgL2FnZW50cy8ke2lkfSR7cXN9YCwge1xuICAgICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICAgIGFwaVZlcnNpb246ICdub25lJyxcbiAgICB9KTtcblxuICAgIGlmIChvcHRpb25zPy5kcnlSdW4pIHtcbiAgICAgIHJldHVybiAocmVzcG9uc2UgYXMgYW55KS5kYXRhID8/IHJlc3BvbnNlO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogR2V0IGFnZW50IGNvbmZpZ3VyYXRpb24gKGJhc2VsaW5lKVxuICAgKi9cbiAgYXN5bmMgZ2V0Q29uZmlnKGFnZW50SWQ6IHN0cmluZyk6IFByb21pc2U8QWdlbnRDb25maWcgfCBudWxsPiB7XG4gICAgaWYgKCFhZ2VudElkKSB0aHJvdyBuZXcgVGhpbmtIaXZlVmFsaWRhdGlvbkVycm9yKCdBZ2VudCBJRCBpcyByZXF1aXJlZCcsICdhZ2VudElkJyk7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGFwaVJlcXVlc3QoYC9hZ2VudHMvJHthZ2VudElkfS9jb25maWdgLCB7IGFwaVZlcnNpb246ICdub25lJyB9KTtcbiAgICByZXR1cm4gKHJlc3BvbnNlIGFzIGFueSk/LmRhdGEgPz8gcmVzcG9uc2UgPz8gbnVsbDtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlIG9yIHVwZGF0ZSBhZ2VudCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBhc3luYyB1cGRhdGVDb25maWcoYWdlbnRJZDogc3RyaW5nLCBjb25maWc6IFVwZGF0ZUFnZW50Q29uZmlnT3B0aW9ucyk6IFByb21pc2U8QWdlbnRDb25maWc+IHtcbiAgICBpZiAoIWFnZW50SWQpIHRocm93IG5ldyBUaGlua0hpdmVWYWxpZGF0aW9uRXJyb3IoJ0FnZW50IElEIGlzIHJlcXVpcmVkJywgJ2FnZW50SWQnKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXBpUmVxdWVzdChgL2FnZW50cy8ke2FnZW50SWR9L2NvbmZpZ2AsIHtcbiAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICBib2R5OiBjb25maWcsXG4gICAgICBhcGlWZXJzaW9uOiAnbm9uZScsXG4gICAgfSk7XG4gICAgcmV0dXJuIChyZXNwb25zZSBhcyBhbnkpLmRhdGEgPz8gcmVzcG9uc2U7XG4gIH0sXG59O1xuIl19
|