@metrxbot/sdk 0.1.0 → 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 +40 -12
- package/dist/client.d.ts +18 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +68 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/task.d.ts +99 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +104 -0
- package/dist/task.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,9 +28,7 @@ const client = new MetrxbotClient({
|
|
|
28
28
|
```typescript
|
|
29
29
|
const response = await client.chat({
|
|
30
30
|
model: 'gpt-4',
|
|
31
|
-
messages: [
|
|
32
|
-
{ role: 'user', content: 'What is 2+2?' }
|
|
33
|
-
],
|
|
31
|
+
messages: [{ role: 'user', content: 'What is 2+2?' }],
|
|
34
32
|
customerId: 'user-123', // optional, for tracking
|
|
35
33
|
sessionId: 'session-456', // optional, for tracking
|
|
36
34
|
});
|
|
@@ -45,9 +43,7 @@ console.log(`Latency: ${response._meta.latencyMs}ms`);
|
|
|
45
43
|
```typescript
|
|
46
44
|
const stream = client.chatStream({
|
|
47
45
|
model: 'gpt-4',
|
|
48
|
-
messages: [
|
|
49
|
-
{ role: 'user', content: 'Write a haiku' }
|
|
50
|
-
]
|
|
46
|
+
messages: [{ role: 'user', content: 'Write a haiku' }],
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
for await (const chunk of stream) {
|
|
@@ -63,9 +59,7 @@ for await (const chunk of stream) {
|
|
|
63
59
|
const response = await client.messages({
|
|
64
60
|
model: 'claude-3-sonnet',
|
|
65
61
|
max_tokens: 1024,
|
|
66
|
-
messages: [
|
|
67
|
-
{ role: 'user', content: 'Hello, Claude!' }
|
|
68
|
-
]
|
|
62
|
+
messages: [{ role: 'user', content: 'Hello, Claude!' }],
|
|
69
63
|
});
|
|
70
64
|
|
|
71
65
|
console.log(response.content[0].text);
|
|
@@ -76,7 +70,7 @@ console.log(response.content[0].text);
|
|
|
76
70
|
```typescript
|
|
77
71
|
const response = await client.embeddings({
|
|
78
72
|
model: 'text-embedding-3-small',
|
|
79
|
-
input: 'Hello world'
|
|
73
|
+
input: 'Hello world',
|
|
80
74
|
});
|
|
81
75
|
|
|
82
76
|
console.log(response.data[0].embedding);
|
|
@@ -94,7 +88,7 @@ console.log(health.version);
|
|
|
94
88
|
|
|
95
89
|
```typescript
|
|
96
90
|
const models = await client.models();
|
|
97
|
-
console.log(models.data.map(m => m.id));
|
|
91
|
+
console.log(models.data.map((m) => m.id));
|
|
98
92
|
```
|
|
99
93
|
|
|
100
94
|
## Configuration
|
|
@@ -160,7 +154,7 @@ import {
|
|
|
160
154
|
try {
|
|
161
155
|
const response = await client.chat({
|
|
162
156
|
model: 'gpt-4',
|
|
163
|
-
messages: [{ role: 'user', content: 'Hello' }]
|
|
157
|
+
messages: [{ role: 'user', content: 'Hello' }],
|
|
164
158
|
});
|
|
165
159
|
} catch (error) {
|
|
166
160
|
if (error instanceof AuthenticationError) {
|
|
@@ -202,6 +196,40 @@ interface MetrxbotMeta {
|
|
|
202
196
|
- Deno
|
|
203
197
|
- Modern browsers (with native fetch support)
|
|
204
198
|
|
|
199
|
+
## Cascade routing (v0.2.0, opt-in)
|
|
200
|
+
|
|
201
|
+
Delegate per-request model choice to Metrx **inside your own process** — your
|
|
202
|
+
provider keys never leave your environment, and prompt/output text is never
|
|
203
|
+
sent to Metrx (scores only).
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { MetrxbotClient, runWithPolicy } from '@metrxbot/sdk';
|
|
207
|
+
|
|
208
|
+
const metrx = new MetrxbotClient({ apiKey: process.env.METRX_API_KEY! });
|
|
209
|
+
|
|
210
|
+
const r = await runWithPolicy(metrx, {
|
|
211
|
+
agentKey: 'ask_fundry',
|
|
212
|
+
input: prompt,
|
|
213
|
+
// Your own provider call — your client, your keys.
|
|
214
|
+
// model === undefined ⇒ call your own default (day-0 pass-through).
|
|
215
|
+
callModel: (model, input) => callAnthropic(model ?? DEFAULT_MODEL, input),
|
|
216
|
+
// Cross-family checker (required before shadow/cascade modes are enabled):
|
|
217
|
+
checkerCaller: (model, task) => callOpenAI(model!, task),
|
|
218
|
+
});
|
|
219
|
+
use(r.output);
|
|
220
|
+
// Attach r.requestId to your telemetry events (request_id field) so cost
|
|
221
|
+
// joins work: it links llm_events ↔ optimization_decisions ↔ quality.
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Behavior is controlled server-side per agent (`routing_policies`): with no
|
|
225
|
+
policy row every call is an exact pass-through. Modes advance
|
|
226
|
+
`pass_through → shadow_sample → cascade`, each gated by evidence. **Every
|
|
227
|
+
seam fails open** — no code path throws an error your own
|
|
228
|
+
`callModel(prodModel)` would not have thrown. Kill switches: server policy
|
|
229
|
+
`enabled=false`, env `METRX_ROUTING_DISABLED=true`, `min_sdk_version`.
|
|
230
|
+
|
|
231
|
+
Not supported in v1: streaming call sites (keep them on their original path).
|
|
232
|
+
|
|
205
233
|
## License
|
|
206
234
|
|
|
207
235
|
MIT
|
package/dist/client.d.ts
CHANGED
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
* Main SDK client for interacting with the Metrx gateway
|
|
4
4
|
*/
|
|
5
5
|
import { MetrxbotConfig, ChatCompletionParams, ChatCompletionResponse, EmbeddingsParams, EmbeddingsResponse, HealthResponse, MessagesParams, MessagesResponse, ModelsResponse, StreamChunk } from './types';
|
|
6
|
+
import { type TaskOutcome } from './task';
|
|
7
|
+
export interface SubmitOutcomeResponse {
|
|
8
|
+
outcome_id: string;
|
|
9
|
+
task_id: string;
|
|
10
|
+
source: 'sdk_asserted';
|
|
11
|
+
confidence_tier: 'human_verified';
|
|
12
|
+
}
|
|
6
13
|
export declare class MetrxbotClient {
|
|
7
14
|
private apiKey;
|
|
8
15
|
private gatewayUrl;
|
|
16
|
+
private apiUrl;
|
|
9
17
|
private defaultAgentId?;
|
|
10
18
|
private defaultProvider?;
|
|
11
19
|
private timeout;
|
|
@@ -46,6 +54,16 @@ export declare class MetrxbotClient {
|
|
|
46
54
|
* Internal: Build request headers
|
|
47
55
|
*/
|
|
48
56
|
private buildHeaders;
|
|
57
|
+
/**
|
|
58
|
+
* Submit an SDK-asserted outcome for a completed task. Calls
|
|
59
|
+
* `POST {apiUrl}/api/v1/tasks/:task_id/outcome` (Session 3 endpoint).
|
|
60
|
+
*
|
|
61
|
+
* Idempotent server-side via UNIQUE(org_id, source, reference_id);
|
|
62
|
+
* re-submitting with the same task_id updates rather than duplicates.
|
|
63
|
+
*
|
|
64
|
+
* Prefer calling this through `task()` which handles it automatically.
|
|
65
|
+
*/
|
|
66
|
+
submitOutcome(taskId: string, outcome: TaskOutcome): Promise<SubmitOutcomeResponse>;
|
|
49
67
|
/**
|
|
50
68
|
* Internal: Extract metadata from response headers
|
|
51
69
|
*/
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EAEd,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EAEd,WAAW,EACZ,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EAEd,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EAEd,WAAW,EACZ,MAAM,SAAS,CAAC;AASjB,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAMzD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,EAAE,gBAAgB,CAAC;CACnC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,cAAc;IAuBlC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAIvC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAIvC;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IASzE;;OAEG;IACI,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CAAC,WAAW,CAAC;IAyD3E;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIjE;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIvE;;OAEG;YACW,OAAO;IAsBrB;;OAEG;YACW,QAAQ;IAsCtB;;OAEG;IACH,OAAO,CAAC,YAAY;IAwCpB;;;;;;;;OAQG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAwCzF;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;YACW,mBAAmB;CAiClC"}
|
package/dist/client.js
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
* Main SDK client for interacting with the Metrx gateway
|
|
4
4
|
*/
|
|
5
5
|
import { MetrxbotError, AuthenticationError, GatewayError, RateLimitError, TimeoutError, ValidationError, } from './errors';
|
|
6
|
+
import { currentTaskId } from './task';
|
|
6
7
|
const DEFAULT_GATEWAY_URL = 'https://gateway.metrxbot.com';
|
|
8
|
+
const DEFAULT_API_URL = 'https://metrxbot.com';
|
|
7
9
|
const DEFAULT_TIMEOUT = 30000; // 30 seconds
|
|
8
10
|
export class MetrxbotClient {
|
|
9
11
|
apiKey;
|
|
10
12
|
gatewayUrl;
|
|
13
|
+
apiUrl;
|
|
11
14
|
defaultAgentId;
|
|
12
15
|
defaultProvider;
|
|
13
16
|
timeout;
|
|
@@ -17,6 +20,17 @@ export class MetrxbotClient {
|
|
|
17
20
|
}
|
|
18
21
|
this.apiKey = config.apiKey;
|
|
19
22
|
this.gatewayUrl = config.gatewayUrl || DEFAULT_GATEWAY_URL;
|
|
23
|
+
this.apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
24
|
+
// The apiUrl receives the Bearer API key on submitOutcome(). Reject
|
|
25
|
+
// plaintext http:// so a misconfigured SDK cannot leak credentials
|
|
26
|
+
// to an attacker-controlled origin. localhost/127.0.0.1 is allowed
|
|
27
|
+
// unencrypted to keep local dev ergonomics.
|
|
28
|
+
if (!/^https:\/\//i.test(this.apiUrl)) {
|
|
29
|
+
const isLocal = /^http:\/\/(localhost|127\.0\.0\.1)(:|\/|$)/i.test(this.apiUrl);
|
|
30
|
+
if (!isLocal) {
|
|
31
|
+
throw new ValidationError('apiUrl must use https:// (got: ' + this.apiUrl + ')');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
20
34
|
this.defaultAgentId = config.defaultAgentId;
|
|
21
35
|
this.defaultProvider = config.defaultProvider;
|
|
22
36
|
this.timeout = config.timeout || DEFAULT_TIMEOUT;
|
|
@@ -170,8 +184,60 @@ export class MetrxbotClient {
|
|
|
170
184
|
if (provider) {
|
|
171
185
|
headers['X-Provider'] = provider;
|
|
172
186
|
}
|
|
187
|
+
// Session 4: task() AsyncLocalStorage → X-Task-Id. Explicit
|
|
188
|
+
// options.taskId always wins so advanced callers can override.
|
|
189
|
+
// Gateway reads this header and writes it to llm_events.task_id
|
|
190
|
+
// (migration 056).
|
|
191
|
+
const taskId = options?.taskId ?? currentTaskId();
|
|
192
|
+
if (taskId) {
|
|
193
|
+
headers['X-Task-Id'] = taskId;
|
|
194
|
+
}
|
|
173
195
|
return headers;
|
|
174
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Submit an SDK-asserted outcome for a completed task. Calls
|
|
199
|
+
* `POST {apiUrl}/api/v1/tasks/:task_id/outcome` (Session 3 endpoint).
|
|
200
|
+
*
|
|
201
|
+
* Idempotent server-side via UNIQUE(org_id, source, reference_id);
|
|
202
|
+
* re-submitting with the same task_id updates rather than duplicates.
|
|
203
|
+
*
|
|
204
|
+
* Prefer calling this through `task()` which handles it automatically.
|
|
205
|
+
*/
|
|
206
|
+
async submitOutcome(taskId, outcome) {
|
|
207
|
+
if (!taskId || typeof taskId !== 'string') {
|
|
208
|
+
throw new ValidationError('taskId is required');
|
|
209
|
+
}
|
|
210
|
+
const url = `${this.apiUrl}/api/v1/tasks/${encodeURIComponent(taskId)}/outcome`;
|
|
211
|
+
const headers = {
|
|
212
|
+
'Content-Type': 'application/json',
|
|
213
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
214
|
+
};
|
|
215
|
+
const controller = new AbortController();
|
|
216
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
217
|
+
let response;
|
|
218
|
+
try {
|
|
219
|
+
response = await fetch(url, {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers,
|
|
222
|
+
body: JSON.stringify(outcome),
|
|
223
|
+
signal: controller.signal,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
228
|
+
throw new TimeoutError(`Outcome submission timeout after ${this.timeout}ms`);
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
clearTimeout(timeoutId);
|
|
234
|
+
}
|
|
235
|
+
if (!response.ok) {
|
|
236
|
+
await this.handleErrorResponse(response);
|
|
237
|
+
}
|
|
238
|
+
const body = (await response.json());
|
|
239
|
+
return body.data;
|
|
240
|
+
}
|
|
175
241
|
/**
|
|
176
242
|
* Internal: Extract metadata from response headers
|
|
177
243
|
*/
|
|
@@ -205,9 +271,10 @@ export class MetrxbotClient {
|
|
|
205
271
|
throw new ValidationError(errorMessage, requestId);
|
|
206
272
|
case 401:
|
|
207
273
|
throw new AuthenticationError(errorMessage, requestId);
|
|
208
|
-
case 429:
|
|
274
|
+
case 429: {
|
|
209
275
|
const retryAfter = response.headers.get('Retry-After');
|
|
210
276
|
throw new RateLimitError(errorMessage, retryAfter || undefined, requestId);
|
|
277
|
+
}
|
|
211
278
|
case 502:
|
|
212
279
|
case 504:
|
|
213
280
|
throw new GatewayError(errorMessage, response.status, requestId);
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAoB,MAAM,QAAQ,CAAC;AAEzD,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAC3D,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAC/C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,aAAa;AAS5C,MAAM,OAAO,cAAc;IACjB,MAAM,CAAS;IACf,UAAU,CAAS;IACnB,MAAM,CAAS;IACf,cAAc,CAAU;IACxB,eAAe,CAAU;IACzB,OAAO,CAAS;IAExB,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,eAAe,CAAC,oBAAoB,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAC;QAC3D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;QAC/C,oEAAoE;QACpE,mEAAmE;QACnE,mEAAmE;QACnE,4CAA4C;QAC5C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,6CAA6C,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,eAAe,CAAC,iCAAiC,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,eAAe,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,OAAO,CAAiB,KAAK,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,OAAO,CAAiB,KAAK,EAAE,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,MAA4B;QACrC,OAAO,IAAI,CAAC,OAAO,CACjB,MAAM,EACN,sBAAsB,EACtB,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAC5B,MAAM,CACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAC,UAAU,CAAC,MAA4B;QAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAClC,MAAM,EACN,sBAAsB,EACtB,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAC3B,MAAM,CACP,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,aAAa,CAAC,wCAAwC,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAElC,IAAI,CAAC;YACH,IAAI,MAAM,GAAG,EAAE,CAAC;YAEhB,OAAO,IAAI,EAAE,CAAC;gBACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAE5C,IAAI,IAAI;oBAAE,MAAM;gBAEhB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBAElD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;wBAAE,SAAS;oBAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;wBAAE,SAAS;oBAEzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAElC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;wBACtB,MAAM;oBACR,CAAC;oBAED,IAAI,CAAC;wBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;wBAC9C,wCAAwC;wBACxC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;wBAC7C,MAAM,KAAK,CAAC;oBACd,CAAC;oBAAC,MAAM,CAAC;wBACP,sBAAsB;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAsB;QACnC,OAAO,IAAI,CAAC,OAAO,CAAmB,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,MAAwB;QACvC,OAAO,IAAI,CAAC,OAAO,CAAqB,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,OAAO,CACnB,MAAsB,EACtB,IAAY,EACZ,IAAc,EACd,OAAwB;QAExB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAElE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiC,CAAC;QAErE,wCAAwC;QACxC,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAY,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,QAAQ,CACpB,MAAsB,EACtB,IAAY,EACZ,IAAc,EACd,OAAwB;QAExB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAgB;YACxB,MAAM;YACN,OAAO;SACR,CAAC;QAEF,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAErE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,GAAG,IAAI;gBACP,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1D,MAAM,IAAI,YAAY,CAAC,yBAAyB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;YACpE,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,OAAwB;QAC3C,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC;QACxD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC;QAClC,CAAC;QAED,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;YACxB,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;QAChD,CAAC;QAED,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;QAC9C,CAAC;QAED,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;YACzB,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAClD,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC;QAC3D,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;QACnC,CAAC;QAED,4DAA4D;QAC5D,+DAA+D;QAC/D,gEAAgE;QAChE,mBAAmB;QACnB,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC;QAChC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,OAAoB;QACtD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,eAAe,CAAC,oBAAoB,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,iBAAiB,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC;QAChF,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAErE,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC1B,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1D,MAAM,IAAI,YAAY,CAAC,oCAAoC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;YAC/E,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;QACF,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,QAAkB;QACxC,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QACjF,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QACnF,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;QAEpE,OAAO;YACL,SAAS;YACT,cAAc;YACd,SAAS,EAAE,SAAS,IAAI,SAAS;SAClC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAAC,QAAkB;QAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;QACpE,IAAI,YAAY,GAAG,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QAE7C,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAQ,CAAC;YACjD,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;gBAC7B,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YACzC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;QAED,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxB,KAAK,GAAG;gBACN,MAAM,IAAI,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAErD,KAAK,GAAG;gBACN,MAAM,IAAI,mBAAmB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAEzD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACvD,MAAM,IAAI,cAAc,CAAC,YAAY,EAAE,UAAU,IAAI,SAAS,EAAE,SAAS,CAAC,CAAC;YAC7E,CAAC;YAED,KAAK,GAAG,CAAC;YACT,KAAK,GAAG;gBACN,MAAM,IAAI,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAEnE;gBACE,MAAM,IAAI,aAAa,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
* TypeScript SDK for integrating with Metrx gateway
|
|
4
4
|
*/
|
|
5
5
|
export { MetrxbotClient } from './client';
|
|
6
|
+
export type { SubmitOutcomeResponse } from './client';
|
|
7
|
+
export { task, currentTaskId } from './task';
|
|
8
|
+
export type { TaskContext, TaskOutcome, TaskOptions, OutcomeSubmitter, BenchLytixCategory, } from './task';
|
|
6
9
|
export { MetrxbotSpanExporter } from './otel';
|
|
7
10
|
export type { MetrxbotConfig, MetrxbotMeta, RequestOptions, ChatCompletionParams, ChatCompletionResponse, ChatMessage, ChatChoice, StreamChunk, StreamChoice, MessagesParams, MessagesResponse, AnthropicMessage, AnthropicContent, MessageContent, EmbeddingsParams, EmbeddingsResponse, Embedding, HealthResponse, ModelsResponse, Model, APIError, OtelExporterConfig, } from './types';
|
|
8
11
|
export { MetrxbotError, AuthenticationError, RateLimitError, GatewayError, ValidationError, TimeoutError, isMetrxbotError, } from './errors';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGtD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAG9C,YAAY,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,cAAc,EACd,KAAK,EACL,QAAQ,EACR,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,eAAe,GAChB,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* TypeScript SDK for integrating with Metrx gateway
|
|
4
4
|
*/
|
|
5
5
|
export { MetrxbotClient } from './client';
|
|
6
|
+
// Session 4: task() context + outcome correlation
|
|
7
|
+
export { task, currentTaskId } from './task';
|
|
6
8
|
// OpenTelemetry Exporter
|
|
7
9
|
export { MetrxbotSpanExporter } from './otel';
|
|
8
10
|
// Errors
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,kDAAkD;AAClD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAS7C,yBAAyB;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AA4B9C,SAAS;AACT,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,eAAe,GAChB,MAAM,UAAU,CAAC"}
|
package/dist/task.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK v2 task() context — BenchLytix Token Economy (Session 4)
|
|
3
|
+
*
|
|
4
|
+
* Correlates a unit of agent work to a single task_id so that:
|
|
5
|
+
* 1. Any MetrxbotClient calls made inside the block thread `X-Task-Id`
|
|
6
|
+
* on the gateway request — the gateway writes this onto `llm_events`
|
|
7
|
+
* (migration 056 column).
|
|
8
|
+
* 2. After the block completes, an outcome row is POSTed to
|
|
9
|
+
* /api/v1/tasks/:task_id/outcome (Session 3 endpoint) with the
|
|
10
|
+
* outcome the caller captured via `setOutcome`.
|
|
11
|
+
*
|
|
12
|
+
* Propagation is async-safe via Node's AsyncLocalStorage (Node >=18).
|
|
13
|
+
*
|
|
14
|
+
* Example::
|
|
15
|
+
*
|
|
16
|
+
* import { MetrxbotClient, task } from '@metrxbot/sdk';
|
|
17
|
+
* const client = new MetrxbotClient({ apiKey });
|
|
18
|
+
*
|
|
19
|
+
* await task(client, async (ctx) => {
|
|
20
|
+
* const res = await client.chat({ model: 'gpt-4o', messages: [...] });
|
|
21
|
+
* ctx.setOutcome({ success: true, value_microcents: 250_000 });
|
|
22
|
+
* return res;
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // gateway saw X-Task-Id = ctx.taskId on the chat request;
|
|
26
|
+
* // /api/v1/tasks/{ctx.taskId}/outcome POSTed afterwards.
|
|
27
|
+
*
|
|
28
|
+
* Design rules:
|
|
29
|
+
* - Never mask the user's thrown error with an outcome-submission error.
|
|
30
|
+
* - If the block throws and autoOutcomeOnError=true (default), a
|
|
31
|
+
* success:false outcome is best-effort posted with the error message
|
|
32
|
+
* folded into metadata.
|
|
33
|
+
* - If the block completes without calling setOutcome(), NO outcome is
|
|
34
|
+
* posted. The task_id was still correlated on any gateway calls via
|
|
35
|
+
* X-Task-Id, which is enough for observability-only usage.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* BenchLytix category enum (mirrors packages/types/src/index.ts
|
|
39
|
+
* BenchLytixCategory). Duplicated locally so the SDK has no workspace
|
|
40
|
+
* dependency on @metrx/types. Server-side revalidates in Session 3.
|
|
41
|
+
*/
|
|
42
|
+
export type BenchLytixCategory = 'legal-summarization' | 'code-generation' | 'data-extraction' | 'customer-support' | 'meeting-summarization' | 'financial-analysis' | 'web-research' | 'content-generation' | 'classification' | 'multi-step-reasoning' | 'unmapped';
|
|
43
|
+
export interface TaskOutcome {
|
|
44
|
+
/** Did the unit of work succeed from the caller's POV? */
|
|
45
|
+
success: boolean;
|
|
46
|
+
/** Business value in microcents (divide by 10_000 for cents). */
|
|
47
|
+
value_microcents?: number;
|
|
48
|
+
/** Optional BenchLytix category tag — server revalidates. */
|
|
49
|
+
category?: BenchLytixCategory;
|
|
50
|
+
/** Arbitrary key/value metadata. */
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
/** Free-form notes string. */
|
|
53
|
+
notes?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface TaskOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Override task_id. Default: crypto.randomUUID() (v4). Callers pass
|
|
58
|
+
* their own only when they already have a correlation key (e.g. a
|
|
59
|
+
* queue message id) they want to tie back to llm_events.
|
|
60
|
+
*/
|
|
61
|
+
taskId?: string;
|
|
62
|
+
/**
|
|
63
|
+
* When the block throws, auto-submit a success:false outcome.
|
|
64
|
+
* Default: true. The original error is always re-thrown regardless.
|
|
65
|
+
*/
|
|
66
|
+
autoOutcomeOnError?: boolean;
|
|
67
|
+
}
|
|
68
|
+
export interface TaskContext {
|
|
69
|
+
readonly taskId: string;
|
|
70
|
+
/** Record an outcome for this task. Overwrites any previous call. */
|
|
71
|
+
setOutcome(outcome: TaskOutcome): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Narrow contract for the outcome poster — lets `task()` be called with
|
|
75
|
+
* any object that knows how to submit outcomes. MetrxbotClient satisfies
|
|
76
|
+
* this via its `submitOutcome(taskId, outcome)` method (client.ts).
|
|
77
|
+
*/
|
|
78
|
+
export interface OutcomeSubmitter {
|
|
79
|
+
submitOutcome(taskId: string, outcome: TaskOutcome): Promise<unknown>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Return the task_id of the currently-active task context, or undefined
|
|
83
|
+
* if not inside a task() block. Used by MetrxbotClient.buildHeaders to
|
|
84
|
+
* auto-inject X-Task-Id.
|
|
85
|
+
*/
|
|
86
|
+
export declare function currentTaskId(): string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Run `fn` inside a task context with auto-correlation + outcome.
|
|
89
|
+
*
|
|
90
|
+
* - The callback receives `{ taskId, setOutcome }`.
|
|
91
|
+
* - Any MetrxbotClient requests made inside receive X-Task-Id header
|
|
92
|
+
* automatically (via currentTaskId() lookup in buildHeaders).
|
|
93
|
+
* - If the callback throws, the original error is re-thrown. A
|
|
94
|
+
* best-effort failure outcome is posted first (unless disabled).
|
|
95
|
+
* - If the callback returns normally AND setOutcome was called, the
|
|
96
|
+
* outcome is posted before returning the result.
|
|
97
|
+
*/
|
|
98
|
+
export declare function task<T>(submitter: OutcomeSubmitter, fn: (ctx: TaskContext) => Promise<T>, opts?: TaskOptions): Promise<T>;
|
|
99
|
+
//# sourceMappingURL=task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAKH;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B,qBAAqB,GACrB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,uBAAuB,GACvB,oBAAoB,GACpB,cAAc,GACd,oBAAoB,GACpB,gBAAgB,GAChB,sBAAsB,GACtB,UAAU,CAAC;AAEf,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;CACxC;AAQD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAID;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,SAAS,CAElD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,IAAI,CAAC,CAAC,EAC1B,SAAS,EAAE,gBAAgB,EAC3B,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACpC,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,CAAC,CAAC,CA+CZ"}
|
package/dist/task.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK v2 task() context — BenchLytix Token Economy (Session 4)
|
|
3
|
+
*
|
|
4
|
+
* Correlates a unit of agent work to a single task_id so that:
|
|
5
|
+
* 1. Any MetrxbotClient calls made inside the block thread `X-Task-Id`
|
|
6
|
+
* on the gateway request — the gateway writes this onto `llm_events`
|
|
7
|
+
* (migration 056 column).
|
|
8
|
+
* 2. After the block completes, an outcome row is POSTed to
|
|
9
|
+
* /api/v1/tasks/:task_id/outcome (Session 3 endpoint) with the
|
|
10
|
+
* outcome the caller captured via `setOutcome`.
|
|
11
|
+
*
|
|
12
|
+
* Propagation is async-safe via Node's AsyncLocalStorage (Node >=18).
|
|
13
|
+
*
|
|
14
|
+
* Example::
|
|
15
|
+
*
|
|
16
|
+
* import { MetrxbotClient, task } from '@metrxbot/sdk';
|
|
17
|
+
* const client = new MetrxbotClient({ apiKey });
|
|
18
|
+
*
|
|
19
|
+
* await task(client, async (ctx) => {
|
|
20
|
+
* const res = await client.chat({ model: 'gpt-4o', messages: [...] });
|
|
21
|
+
* ctx.setOutcome({ success: true, value_microcents: 250_000 });
|
|
22
|
+
* return res;
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // gateway saw X-Task-Id = ctx.taskId on the chat request;
|
|
26
|
+
* // /api/v1/tasks/{ctx.taskId}/outcome POSTed afterwards.
|
|
27
|
+
*
|
|
28
|
+
* Design rules:
|
|
29
|
+
* - Never mask the user's thrown error with an outcome-submission error.
|
|
30
|
+
* - If the block throws and autoOutcomeOnError=true (default), a
|
|
31
|
+
* success:false outcome is best-effort posted with the error message
|
|
32
|
+
* folded into metadata.
|
|
33
|
+
* - If the block completes without calling setOutcome(), NO outcome is
|
|
34
|
+
* posted. The task_id was still correlated on any gateway calls via
|
|
35
|
+
* X-Task-Id, which is enough for observability-only usage.
|
|
36
|
+
*/
|
|
37
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
38
|
+
import { randomUUID } from 'node:crypto';
|
|
39
|
+
const _storage = new AsyncLocalStorage();
|
|
40
|
+
/**
|
|
41
|
+
* Return the task_id of the currently-active task context, or undefined
|
|
42
|
+
* if not inside a task() block. Used by MetrxbotClient.buildHeaders to
|
|
43
|
+
* auto-inject X-Task-Id.
|
|
44
|
+
*/
|
|
45
|
+
export function currentTaskId() {
|
|
46
|
+
return _storage.getStore()?.taskId;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Run `fn` inside a task context with auto-correlation + outcome.
|
|
50
|
+
*
|
|
51
|
+
* - The callback receives `{ taskId, setOutcome }`.
|
|
52
|
+
* - Any MetrxbotClient requests made inside receive X-Task-Id header
|
|
53
|
+
* automatically (via currentTaskId() lookup in buildHeaders).
|
|
54
|
+
* - If the callback throws, the original error is re-thrown. A
|
|
55
|
+
* best-effort failure outcome is posted first (unless disabled).
|
|
56
|
+
* - If the callback returns normally AND setOutcome was called, the
|
|
57
|
+
* outcome is posted before returning the result.
|
|
58
|
+
*/
|
|
59
|
+
export async function task(submitter, fn, opts) {
|
|
60
|
+
const taskId = opts?.taskId ?? randomUUID();
|
|
61
|
+
const autoOutcomeOnError = opts?.autoOutcomeOnError !== false;
|
|
62
|
+
const state = { taskId, startedAt: Date.now() };
|
|
63
|
+
const ctx = {
|
|
64
|
+
taskId,
|
|
65
|
+
setOutcome(outcome) {
|
|
66
|
+
state.outcome = outcome;
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
let threw = false;
|
|
70
|
+
let error;
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = await _storage.run(state, () => fn(ctx));
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
threw = true;
|
|
77
|
+
error = err;
|
|
78
|
+
}
|
|
79
|
+
if (threw) {
|
|
80
|
+
if (autoOutcomeOnError) {
|
|
81
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
82
|
+
try {
|
|
83
|
+
await submitter.submitOutcome(taskId, {
|
|
84
|
+
success: false,
|
|
85
|
+
metadata: {
|
|
86
|
+
...(state.outcome?.metadata ?? {}),
|
|
87
|
+
error: errMsg,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Swallow — never mask the caller's original exception with an
|
|
93
|
+
// outcome-submission failure. Transport errors are visible in
|
|
94
|
+
// the SDK's debug logger elsewhere.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
if (state.outcome) {
|
|
100
|
+
await submitter.submitOutcome(taskId, state.outcome);
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=task.js.map
|
package/dist/task.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAoEzC,MAAM,QAAQ,GAAG,IAAI,iBAAiB,EAAa,CAAC;AAEpD;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,QAAQ,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC;AACrC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,SAA2B,EAC3B,EAAoC,EACpC,IAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,UAAU,EAAE,CAAC;IAC5C,MAAM,kBAAkB,GAAG,IAAI,EAAE,kBAAkB,KAAK,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAc,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAE3D,MAAM,GAAG,GAAgB;QACvB,MAAM;QACN,UAAU,CAAC,OAAO;YAChB,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QAC1B,CAAC;KACF,CAAC;IAEF,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,KAAc,CAAC;IACnB,IAAI,MAAqB,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,GAAG,IAAI,CAAC;QACb,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,kBAAkB,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE;oBACpC,OAAO,EAAE,KAAK;oBACd,QAAQ,EAAE;wBACR,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;wBAClC,KAAK,EAAE,MAAM;qBACd;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,+DAA+D;gBAC/D,8DAA8D;gBAC9D,oCAAoC;YACtC,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,MAAW,CAAC;AACrB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,13 @@ export interface MetrxbotConfig {
|
|
|
6
6
|
apiKey: string;
|
|
7
7
|
/** Gateway URL (default: https://gateway.metrxbot.com) */
|
|
8
8
|
gatewayUrl?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Metrx REST API URL (default: https://metrxbot.com). Used for
|
|
11
|
+
* `submitOutcome()` which POSTs to `/api/v1/tasks/:task_id/outcome`
|
|
12
|
+
* on the web origin — this is separate from `gatewayUrl` (the LLM
|
|
13
|
+
* proxy edge).
|
|
14
|
+
*/
|
|
15
|
+
apiUrl?: string;
|
|
9
16
|
/** Default agent ID for all requests */
|
|
10
17
|
defaultAgentId?: string;
|
|
11
18
|
/** Default LLM provider (openai, anthropic, etc.) */
|
|
@@ -32,6 +39,13 @@ export interface RequestOptions {
|
|
|
32
39
|
providerKey?: string;
|
|
33
40
|
/** Force specific provider */
|
|
34
41
|
provider?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Explicit task_id override for this request. Normally unset — when
|
|
44
|
+
* the caller wraps work in `task()` the SDK auto-injects the current
|
|
45
|
+
* task's id via AsyncLocalStorage. Pass this only to override that
|
|
46
|
+
* or to correlate a standalone request.
|
|
47
|
+
*/
|
|
48
|
+
taskId?: string;
|
|
35
49
|
}
|
|
36
50
|
export interface ChatCompletionParams extends RequestOptions {
|
|
37
51
|
model: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IAEf,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAElB,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;IAEvB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|