@lionhummer/constellation 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -94,6 +94,10 @@ Each invocation creates a new request. For application retries, persist the comp
|
|
|
94
94
|
| `waiting` | Handle the pending input. Tools always require a consumer; wait checkpoints do too. SSE observation does not answer inputs. |
|
|
95
95
|
| `failed` | Inspect `request.reason`, `request.error`, attempts and timeline for provider, routing or deadline failure. |
|
|
96
96
|
|
|
97
|
+
## Release 0.4.0
|
|
98
|
+
|
|
99
|
+
Telemetry now returns metadata by default. Use `include: "content"` for full content, with the same permission/scope. Adds key-aware `discover`, explicit request timings, accurate endpoint filter types, HTTP chunk pagination, and billing/traffic methods. Deploy the matching server before using these methods.
|
|
100
|
+
|
|
97
101
|
## Release 0.3.0
|
|
98
102
|
|
|
99
103
|
This pre-1.0 release breaks the earlier SDK contract. Use namespaced execution methods; flat aliases and the old drive/protocol surface are removed. Keys, credentials, users and capacity administration are internal-only. Provider-definition writes also require an internal operator. External telemetry and other registry authoring remain available. Deploy a server containing these API changes before switching clients; publishing this package does not deploy the server or upgrade any downstream application dependency.
|
|
@@ -156,3 +160,44 @@ Use the documented namespaces throughout: `requests.create`, `requests.get`,
|
|
|
156
160
|
`requests.streamEvents`, `inputs.claim`, `inputs.respond`, `spans.start`,
|
|
157
161
|
`spans.add`, and `logs.add`. Their implementation helpers are private; flat
|
|
158
162
|
method aliases are not part of the client API.
|
|
163
|
+
|
|
164
|
+
## Caller failures and delivery retries
|
|
165
|
+
|
|
166
|
+
A failed webhook delivery is one attempt, not the final request outcome. Constellation retains failed attempts even when a later retry succeeds. Retryable delivery warnings include the input ID, attempt number, callback HTTP failure and retry delay; terminal failures remain errors. The callback drawer shows that delivery and the current request state.
|
|
167
|
+
|
|
168
|
+
The SDK records checkpoint and tool exceptions in `attributes.error` on the caller span and preserves the original exception. Root-cause name, bounded message and optional code are included; SQL dumps, stack traces and arbitrary error object fields are omitted, and common credential forms are redacted. This is best-effort redaction: keep sensitive values out of exception messages. Closed error spans with these details produce one linked request error log. Keep complete diagnostics in your application's own logs. Historical spans without error attributes cannot reconstruct the original exception.
|
|
169
|
+
|
|
170
|
+
## Discover available HTTP operations
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const contract = await client.discover();
|
|
174
|
+
console.log(contract["x-constellation-access"]);
|
|
175
|
+
console.log(Object.keys(contract.paths));
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`discover(signal?)` calls `GET /v1/discover` with the client's bearer key and returns a typed OpenAPI document filtered to that key's permissions and workspace/user scope. It works with execution, management or telemetry keys. `/v1/openapi.json` is the secondary HTTP path. This describes available operations; resource ownership, model access and request lifecycle are still validated when calling them. Discovery does not grant additional access. Requires a server with the discovery endpoint deployed.
|
|
179
|
+
|
|
180
|
+
## Scoped telemetry and timing
|
|
181
|
+
|
|
182
|
+
Telemetry returns metadata by default: request identity/status, timestamps, costs, token counts, attempt commitment/fallback flags and record metadata. Full request/log/HTTP content requires `include: "content"`; this uses the same telemetry permission and key scope, with no extra permission. SDK content fields are optional because the default omits them. Workspace and user scope applies to hot and archived requests, events, records, HTTP, timing and timeline navigation. Global telemetry endpoints require an unscoped key.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
const page = await client.telemetry.requests.list({ externalId: "thread-123", limit: 25 });
|
|
186
|
+
for (const request of page.items) {
|
|
187
|
+
const timing = await client.telemetry.requests.getTimings(request.id);
|
|
188
|
+
console.log(request.status, timing.queueMs, timing.attempts);
|
|
189
|
+
}
|
|
190
|
+
const detail = await client.telemetry.requests.get(requestId, { include: "content" });
|
|
191
|
+
const logs = await client.telemetry.requests.listRecords(requestId, "logs", {
|
|
192
|
+
level: "warn", offset: 0, limit: 25, include: "content",
|
|
193
|
+
});
|
|
194
|
+
const body = await client.telemetry.requests.getHttpBody(requestId, attemptId, {
|
|
195
|
+
direction: "response", offset: 0, limit: 16384, include: "content",
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`requests.getTimings` is also available with execution authority. Timing responses include admission, queue, worker preparation, provider attempts and caller waits. Admission and preparation have recorded child/detail spans; IDs and provenance match the console. Concurrent waits count once in `callerWaitMs`. Missing/incomplete measurements are null. Read `complete`, `truncated` and `asOf`; grouped totals can overlap and are not additive.
|
|
200
|
+
|
|
201
|
+
Request lists accept `RequestListQuery`, including exact `externalId` and requested-model filters, exclusions and substring matches. Record lists accept `RequestRecordsQuery` (`id`, `q`, log-only `level`, `offset`, `limit`). `PageQuery.filters` belongs only to registry list rows. Every other method has its endpoint's exact query type. See the [HTTP filter matrix](../../docs/api.md#filter-audit-and-exact-query-support) for search semantics, caps, cursor behavior and capabilities not currently provided.
|
|
202
|
+
|
|
203
|
+
Unscoped telemetry also exposes `observability.getBilling`, `getTraffic`, `getTiming`, dashboard and measurement series. Use `providerId` for local series and `upstream` for gateway series. `system.getComponent(component, { status, statusNot, q, offset })` and `jobs.listHistory` page matching operational records; notifications use fixed 25-item pages and status/offset, not generic filters.
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../client-core/src/error-details.ts
|
|
2
|
+
function callerErrorDetails(error) {
|
|
3
|
+
let cause = error;
|
|
4
|
+
const seen = new Set;
|
|
5
|
+
for (let depth = 0;depth < 8 && cause instanceof Error && !seen.has(cause); depth++) {
|
|
6
|
+
seen.add(cause);
|
|
7
|
+
if (!(cause.cause instanceof Error))
|
|
8
|
+
break;
|
|
9
|
+
cause = cause.cause;
|
|
10
|
+
}
|
|
11
|
+
const record = cause && typeof cause === "object" ? cause : {};
|
|
12
|
+
const name = cause instanceof Error ? cause.name.slice(0, 80) : "CallerError";
|
|
13
|
+
const code = typeof record.code === "string" && /^[a-zA-Z0-9_-]{1,80}$/.test(record.code) ? record.code : undefined;
|
|
14
|
+
const raw = cause instanceof Error ? cause.message : "Caller handler threw a non-Error value";
|
|
15
|
+
const message = (/Failed query:|\bparams:/i.test(raw) ? "Caller database operation failed; see caller logs" : raw).replace(/\b(?:Bearer\s+)[^\s,;]+/gi, "Bearer [redacted]").replace(/((?:password|token|secret|api[_-]?key)\s*[=:]\s*)[^\s,;]+/gi, "$1[redacted]").replace(/(https?:\/\/)[^\s/@]+:[^\s/@]+@/gi, "$1[redacted]@").slice(0, 512);
|
|
16
|
+
return { name, message, ...code ? { code } : {} };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ../client-core/src/index.ts
|
|
2
20
|
class ConstellationError extends Error {
|
|
3
21
|
status;
|
|
4
22
|
code;
|
|
@@ -306,7 +324,7 @@ class RequestClient {
|
|
|
306
324
|
await this.#respond(id, pending.id, { ...response, claimId: consumerId }, activeSignal);
|
|
307
325
|
} catch (error) {
|
|
308
326
|
if (!activeSignal?.aborted && !closed)
|
|
309
|
-
await span.end({ status: "error" }, activeSignal).catch(() => {});
|
|
327
|
+
await span.end({ status: "error", attributes: { error: callerErrorDetails(error) } }, activeSignal).catch(() => {});
|
|
310
328
|
throw error;
|
|
311
329
|
}
|
|
312
330
|
}, options.signal);
|
|
@@ -347,6 +365,7 @@ class RequestClient {
|
|
|
347
365
|
const span = await this.#startSpan(id, `tool.${pending.payload.name}`, { stepId: pending.stepId ?? undefined, inputId: pending.id }, activeSignal);
|
|
348
366
|
let result;
|
|
349
367
|
let isError = false;
|
|
368
|
+
let errorDetails;
|
|
350
369
|
try {
|
|
351
370
|
if (pending.payload.validationError)
|
|
352
371
|
throw new Error(pending.payload.validationError);
|
|
@@ -361,9 +380,10 @@ class RequestClient {
|
|
|
361
380
|
} catch (error) {
|
|
362
381
|
activeSignal?.throwIfAborted();
|
|
363
382
|
isError = true;
|
|
383
|
+
errorDetails = callerErrorDetails(error);
|
|
364
384
|
result = { error: error instanceof Error ? error.message : "Tool failed" };
|
|
365
385
|
}
|
|
366
|
-
await span.end({ status: isError ? "error" : "ok" }, activeSignal);
|
|
386
|
+
await span.end({ status: isError ? "error" : "ok", ...errorDetails ? { attributes: { error: errorDetails } } : {} }, activeSignal);
|
|
367
387
|
await this.#claim(id, pending.id, consumerId, activeSignal);
|
|
368
388
|
await this.#respond(id, pending.id, { result, isError, claimId: consumerId }, activeSignal);
|
|
369
389
|
}, options.signal);
|
|
@@ -389,13 +409,16 @@ class RequestClient {
|
|
|
389
409
|
preview: (input, signal) => this.#resolve(input, signal),
|
|
390
410
|
get: (id, signal) => this.#inspect(id, signal),
|
|
391
411
|
getSummary: (id, signal) => this.#inspectSummary(id, signal),
|
|
412
|
+
getTimings: (id, signal) => this.#call(`/v1/requests/${encodeURIComponent(id)}/timings`, "GET", undefined, signal),
|
|
392
413
|
list: (query = {}, signal) => this.#list(query, signal),
|
|
393
414
|
cancel: (id, signal) => this.#cancel(id, signal),
|
|
394
415
|
listEvents: (id, after = 0, signal) => this.#call(`/v1/requests/${encodeURIComponent(id)}/events${queryString({ after })}`, "GET", undefined, signal),
|
|
395
416
|
streamEvents: (id, options = {}) => this.#events(id, options),
|
|
396
417
|
listRecords: (id, kind, query = {}, signal) => this.#records(id, kind, query, signal),
|
|
397
418
|
getTimeline: (id, options = {}) => this.#timeline(id, options),
|
|
398
|
-
getHttpExchange: (id, attemptId,
|
|
419
|
+
getHttpExchange: (id, attemptId, query = {}, signal) => {
|
|
420
|
+
return this.#call(`/v1/requests/${encodeURIComponent(id)}/http/${encodeURIComponent(attemptId)}${queryString(query)}`, "GET", undefined, signal);
|
|
421
|
+
},
|
|
399
422
|
getHttpBody: (id, attemptId, query, signal) => this.#call(`/v1/requests/${encodeURIComponent(id)}/http/${encodeURIComponent(attemptId)}/body${queryString(query)}`, "GET", undefined, signal)
|
|
400
423
|
};
|
|
401
424
|
}
|
|
@@ -418,7 +441,7 @@ class RequestClient {
|
|
|
418
441
|
}
|
|
419
442
|
}
|
|
420
443
|
|
|
421
|
-
//
|
|
444
|
+
// src/index.ts
|
|
422
445
|
function queryString2(values) {
|
|
423
446
|
const params = new URLSearchParams;
|
|
424
447
|
for (const [key, value] of Object.entries(values))
|
|
@@ -462,6 +485,9 @@ class Constellation extends RequestClient {
|
|
|
462
485
|
}
|
|
463
486
|
return response.status === 204 ? undefined : response.json();
|
|
464
487
|
}
|
|
488
|
+
discover(signal) {
|
|
489
|
+
return this.#call("/v1/discover", "GET", undefined, signal);
|
|
490
|
+
}
|
|
465
491
|
get management() {
|
|
466
492
|
return {
|
|
467
493
|
registry: {
|
|
@@ -478,26 +504,39 @@ class Constellation extends RequestClient {
|
|
|
478
504
|
}
|
|
479
505
|
get telemetry() {
|
|
480
506
|
const requestPath = (id) => `/v1/telemetry/requests/${encodeURIComponent(id)}`;
|
|
507
|
+
const read = (path, options = {}, extra = {}) => {
|
|
508
|
+
const value = options;
|
|
509
|
+
return this.#call(`${path}${queryString2({ ...extra, include: value.include })}`, "GET", undefined, value.signal);
|
|
510
|
+
};
|
|
481
511
|
return {
|
|
482
512
|
requests: {
|
|
483
513
|
list: (query = {}, signal) => this.#call(`/v1/telemetry/requests${queryString2(query)}`, "GET", undefined, signal),
|
|
484
|
-
get: (id,
|
|
485
|
-
getSummary: (id,
|
|
486
|
-
|
|
514
|
+
get: (id, options = {}) => read(requestPath(id), options),
|
|
515
|
+
getSummary: (id, options = {}) => read(requestPath(id), options, { summary: "true" }),
|
|
516
|
+
getTimings: (id, signal) => this.#call(`${requestPath(id)}/timings`, "GET", undefined, signal),
|
|
517
|
+
listEvents: (id, after = 0, options = {}) => read(`${requestPath(id)}/events`, options, { after }),
|
|
487
518
|
listRecords: (id, kind, query = {}, signal) => this.#call(`${requestPath(id)}/records/${kind}${queryString2(query)}`, "GET", undefined, signal),
|
|
488
|
-
getTimeline: (id, options = {}) =>
|
|
489
|
-
getHttpExchange: (id, attemptId,
|
|
519
|
+
getTimeline: (id, options = {}) => read(`${requestPath(id)}/timeline`, options, { requestId: options.requestId }),
|
|
520
|
+
getHttpExchange: (id, attemptId, options = {}) => {
|
|
521
|
+
const value = options;
|
|
522
|
+
return read(`${requestPath(id)}/http/${encodeURIComponent(attemptId)}`, value, { offset: value.offset, limit: value.limit });
|
|
523
|
+
},
|
|
490
524
|
getHttpBody: (id, attemptId, query, signal) => this.#call(`${requestPath(id)}/http/${encodeURIComponent(attemptId)}/body${queryString2(query)}`, "GET", undefined, signal)
|
|
491
525
|
},
|
|
492
526
|
system: {
|
|
493
|
-
get: (
|
|
527
|
+
get: (options = {}) => read("/v1/telemetry/system", options),
|
|
494
528
|
listHistory: (query = {}, signal) => this.#call(`/v1/telemetry/system/history${queryString2(query)}`, "GET", undefined, signal),
|
|
495
|
-
getComponent: (component,
|
|
529
|
+
getComponent: (component, options = {}) => {
|
|
530
|
+
const value = options;
|
|
531
|
+
return read(`/v1/telemetry/system/${encodeURIComponent(component)}`, value, { offset: value.offset, status: value.status, statusNot: value.statusNot, q: value.q });
|
|
532
|
+
}
|
|
496
533
|
},
|
|
497
534
|
observability: {
|
|
498
535
|
get: (query = {}, signal) => this.#call(`/v1/telemetry/observability${queryString2(query)}`, "GET", undefined, signal),
|
|
499
536
|
getSeries: (query, signal) => this.#call(`/v1/telemetry/observability/series${queryString2(query)}`, "GET", undefined, signal),
|
|
500
|
-
getTiming: (query = {}, signal) => this.#call(`/v1/telemetry/observability/timing${queryString2(query)}`, "GET", undefined, signal)
|
|
537
|
+
getTiming: (query = {}, signal) => this.#call(`/v1/telemetry/observability/timing${queryString2(query)}`, "GET", undefined, signal),
|
|
538
|
+
getTraffic: (query = {}, signal) => this.#call(`/v1/telemetry/observability/traffic${queryString2(query)}`, "GET", undefined, signal),
|
|
539
|
+
getBilling: (query = {}, signal) => this.#call(`/v1/telemetry/observability/billing${queryString2(query)}`, "GET", undefined, signal)
|
|
501
540
|
},
|
|
502
541
|
jobs: {
|
|
503
542
|
listHistory: (query = {}, signal) => this.#call(`/v1/telemetry/jobs/history${queryString2(query)}`, "GET", undefined, signal)
|
|
@@ -91,6 +91,9 @@ export type RequestRecord = {
|
|
|
91
91
|
resolution: Json;
|
|
92
92
|
rules: Json;
|
|
93
93
|
createdAt: string;
|
|
94
|
+
receivedAt: string | null;
|
|
95
|
+
queuedAt: string | null;
|
|
96
|
+
claimedAt: string | null;
|
|
94
97
|
endedAt: string | null;
|
|
95
98
|
deadline: string;
|
|
96
99
|
};
|
|
@@ -194,7 +197,7 @@ export type TimelineRow = {
|
|
|
194
197
|
id: string;
|
|
195
198
|
requestId: string;
|
|
196
199
|
parentId: string | null;
|
|
197
|
-
kind: "request" | "step" | "attempt" | "input" | "span" | "phase" | "http_phase";
|
|
200
|
+
kind: "request" | "step" | "attempt" | "input" | "span" | "phase" | "http_phase" | "delivery";
|
|
198
201
|
label: string;
|
|
199
202
|
status: string;
|
|
200
203
|
start: string;
|
|
@@ -327,6 +330,55 @@ export declare class ConstellationError extends Error {
|
|
|
327
330
|
constructor(status: number, code: string, message: string);
|
|
328
331
|
}
|
|
329
332
|
export declare function uuid7(): string;
|
|
333
|
+
/** Provider-reported token counts. Missing usage is unknown, not zero. */
|
|
334
|
+
export type TokenUsage = {
|
|
335
|
+
inputTokens?: number;
|
|
336
|
+
outputTokens?: number;
|
|
337
|
+
cacheReadTokens?: number;
|
|
338
|
+
cacheWriteTokens?: number;
|
|
339
|
+
reasoningTokens?: number;
|
|
340
|
+
partial?: boolean;
|
|
341
|
+
};
|
|
342
|
+
export type TimingInterval = {
|
|
343
|
+
id: string;
|
|
344
|
+
requestId: string;
|
|
345
|
+
parentId?: string | null;
|
|
346
|
+
start: string;
|
|
347
|
+
end: string | null;
|
|
348
|
+
durationMs: number | null;
|
|
349
|
+
kind?: string;
|
|
350
|
+
name?: string;
|
|
351
|
+
source?: string;
|
|
352
|
+
label?: string;
|
|
353
|
+
origin?: "recorded" | "derived";
|
|
354
|
+
derivedFrom?: string[];
|
|
355
|
+
providerId?: string;
|
|
356
|
+
actualModel?: string;
|
|
357
|
+
offeringId?: string;
|
|
358
|
+
committed?: boolean;
|
|
359
|
+
fallback?: boolean;
|
|
360
|
+
status?: string;
|
|
361
|
+
ttftMs?: number | null;
|
|
362
|
+
ttfbMs?: number | null;
|
|
363
|
+
reasoningMs?: number | null;
|
|
364
|
+
outputMs?: number | null;
|
|
365
|
+
httpStatus?: number | null;
|
|
366
|
+
};
|
|
367
|
+
export type RequestTimings = {
|
|
368
|
+
requestId: string;
|
|
369
|
+
totalMs: number | null;
|
|
370
|
+
admissionMs: number | null;
|
|
371
|
+
queueMs: number | null;
|
|
372
|
+
workerPreparationMs: number | null;
|
|
373
|
+
attemptMs: number | null;
|
|
374
|
+
callerWaitMs: number | null;
|
|
375
|
+
phases: TimingInterval[];
|
|
376
|
+
attempts: TimingInterval[];
|
|
377
|
+
callerWaits: TimingInterval[];
|
|
378
|
+
asOf: string;
|
|
379
|
+
complete: boolean;
|
|
380
|
+
truncated: boolean;
|
|
381
|
+
};
|
|
330
382
|
export type RequestRecordsQuery = {
|
|
331
383
|
id?: string;
|
|
332
384
|
q?: string;
|
|
@@ -393,6 +445,7 @@ export declare class RequestClient {
|
|
|
393
445
|
}>;
|
|
394
446
|
get: (id: string, signal?: AbortSignal) => Promise<Inspection>;
|
|
395
447
|
getSummary: (id: string, signal?: AbortSignal) => Promise<Inspection>;
|
|
448
|
+
getTimings: (id: string, signal?: AbortSignal) => Promise<RequestTimings>;
|
|
396
449
|
list: (query?: RequestListQuery, signal?: AbortSignal) => Promise<{
|
|
397
450
|
items: RequestRecord[];
|
|
398
451
|
total: number;
|
|
@@ -417,7 +470,10 @@ export declare class RequestClient {
|
|
|
417
470
|
requestId?: string;
|
|
418
471
|
signal?: AbortSignal;
|
|
419
472
|
}) => Promise<Timeline>;
|
|
420
|
-
getHttpExchange: (id: string, attemptId: string,
|
|
473
|
+
getHttpExchange: (id: string, attemptId: string, query?: {
|
|
474
|
+
offset?: number;
|
|
475
|
+
limit?: number;
|
|
476
|
+
}, signal?: AbortSignal) => Promise<Json>;
|
|
421
477
|
getHttpBody: (id: string, attemptId: string, query: {
|
|
422
478
|
direction: "request" | "response";
|
|
423
479
|
offset?: number;
|
|
@@ -1,7 +1,97 @@
|
|
|
1
1
|
/** External server SDK. Operator APIs and cookie sessions are internal-only clients. */
|
|
2
|
-
import { RequestClient, type WebhookEvent, type Json, type Page, type PageQuery, type ModelResolution, type RequestRecord, type
|
|
2
|
+
import { RequestClient, type WebhookEvent, type Json, type Page, type PageQuery, type ModelResolution, type RequestRecord, type RequestEvent, type RecordTypes, type Timeline, type TimelineRow, type RequestListQuery, type RequestRecordsQuery, type RequestTimings, type TokenUsage } from "../../client-core/src/index";
|
|
3
3
|
export { ConstellationError, uuid7 } from "../../client-core/src/index";
|
|
4
|
-
export type { Json, Tool, ToolCall, Message, RequestEventModes, RequestInput, Status, RequestRecord, Step, Attempt, PreparedStep, PendingInput, Span, TimelineRow, Timeline, Log, Inspection, RecordTypes, InputResponse, InputHandlers, RequestEvent, Page, PageQuery, ModelScope, ModelResolution, WebhookEvent, RequestRecordsQuery, RequestListQuery, StartSpanOptions } from "../../client-core/src/index";
|
|
4
|
+
export type { Json, Tool, ToolCall, Message, RequestEventModes, RequestInput, RequestTimings, TimingInterval, TokenUsage, Status, RequestRecord, Step, Attempt, PreparedStep, PendingInput, Span, TimelineRow, Timeline, Log, Inspection, RecordTypes, InputResponse, InputHandlers, RequestEvent, Page, PageQuery, ModelScope, ModelResolution, WebhookEvent, RequestRecordsQuery, RequestListQuery, StartSpanOptions } from "../../client-core/src/index";
|
|
5
|
+
/** OpenAPI contract filtered to this key's permissions and scope. */
|
|
6
|
+
export type DiscoveryDocument = {
|
|
7
|
+
openapi: string;
|
|
8
|
+
info: {
|
|
9
|
+
title: string;
|
|
10
|
+
version: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
};
|
|
13
|
+
paths: Record<string, Record<string, Json>>;
|
|
14
|
+
components: {
|
|
15
|
+
schemas: Record<string, Json>;
|
|
16
|
+
securitySchemes: Record<string, Json>;
|
|
17
|
+
};
|
|
18
|
+
"x-constellation-access": {
|
|
19
|
+
permissions: string[];
|
|
20
|
+
workspaceId: string | null;
|
|
21
|
+
userId: string | null;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
/** Telemetry excludes request/log/HTTP content unless explicitly requested. No additional permission is required. */
|
|
25
|
+
export type TelemetryPage<T> = Page<T> & {
|
|
26
|
+
metadataOnly?: true;
|
|
27
|
+
};
|
|
28
|
+
export type TelemetryQuery = {
|
|
29
|
+
include?: "content";
|
|
30
|
+
};
|
|
31
|
+
export type TelemetryReadOptions = TelemetryQuery & {
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
};
|
|
34
|
+
export type PaginationQuery = {
|
|
35
|
+
offset?: number;
|
|
36
|
+
limit?: number;
|
|
37
|
+
};
|
|
38
|
+
export type OperationsQuery = {
|
|
39
|
+
offset?: number;
|
|
40
|
+
status?: string;
|
|
41
|
+
statusNot?: string;
|
|
42
|
+
q?: string;
|
|
43
|
+
};
|
|
44
|
+
export type ObservabilityQuery = PaginationQuery & {
|
|
45
|
+
hours?: 1 | 24 | 168;
|
|
46
|
+
providerId?: string;
|
|
47
|
+
modelId?: string;
|
|
48
|
+
upstream?: string;
|
|
49
|
+
q?: string;
|
|
50
|
+
};
|
|
51
|
+
export type LogSearchQuery = PaginationQuery & {
|
|
52
|
+
q?: string;
|
|
53
|
+
level?: "trace" | "debug" | "info" | "warn" | "error";
|
|
54
|
+
levelNot?: "trace" | "debug" | "info" | "warn" | "error";
|
|
55
|
+
target?: string;
|
|
56
|
+
targetNot?: string;
|
|
57
|
+
requestId?: string;
|
|
58
|
+
requestIdNot?: string;
|
|
59
|
+
from?: string;
|
|
60
|
+
to?: string;
|
|
61
|
+
};
|
|
62
|
+
type OptionalContent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
63
|
+
export type TelemetryRequest = OptionalContent<RequestRecord, "output" | "error" | "reason" | "resolution" | "rules">;
|
|
64
|
+
export type TelemetryRecords = {
|
|
65
|
+
steps: OptionalContent<RecordTypes["steps"], "input" | "output" | "resolution" | "rules" | "customerPrice">;
|
|
66
|
+
attempts: OptionalContent<RecordTypes["attempts"], "endpoint" | "parameters" | "supplierPrice" | "customerPrice" | "error">;
|
|
67
|
+
inputs: Partial<RecordTypes["inputs"]> & {
|
|
68
|
+
id: string;
|
|
69
|
+
requestId: string;
|
|
70
|
+
};
|
|
71
|
+
spans: Partial<RecordTypes["spans"]> & {
|
|
72
|
+
id: string;
|
|
73
|
+
requestId: string;
|
|
74
|
+
};
|
|
75
|
+
logs: OptionalContent<RecordTypes["logs"], "message" | "attributes">;
|
|
76
|
+
};
|
|
77
|
+
export type TelemetryTimeline = Omit<Timeline, "rows"> & {
|
|
78
|
+
metadataOnly?: true;
|
|
79
|
+
rows: (Omit<TimelineRow, "label"> & {
|
|
80
|
+
label?: string;
|
|
81
|
+
})[];
|
|
82
|
+
};
|
|
83
|
+
export type TelemetryInspection = {
|
|
84
|
+
metadataOnly?: true;
|
|
85
|
+
request: TelemetryRequest;
|
|
86
|
+
usage?: TokenUsage;
|
|
87
|
+
input?: Json;
|
|
88
|
+
effectiveInput?: Json;
|
|
89
|
+
steps: TelemetryRecords["steps"][];
|
|
90
|
+
attempts: TelemetryRecords["attempts"][];
|
|
91
|
+
inputs: TelemetryRecords["inputs"][];
|
|
92
|
+
spans: TelemetryRecords["spans"][];
|
|
93
|
+
logs: TelemetryRecords["logs"][];
|
|
94
|
+
};
|
|
5
95
|
export declare class Constellation extends RequestClient {
|
|
6
96
|
#private;
|
|
7
97
|
constructor(options: {
|
|
@@ -10,6 +100,8 @@ export declare class Constellation extends RequestClient {
|
|
|
10
100
|
fetch?: typeof fetch;
|
|
11
101
|
timeoutMs?: number;
|
|
12
102
|
});
|
|
103
|
+
/** Discover HTTP operations available to this bearer key. */
|
|
104
|
+
discover(signal?: AbortSignal): Promise<DiscoveryDocument>;
|
|
13
105
|
/** Registry authoring only; keys, credentials and capacity controls are internal. */
|
|
14
106
|
get management(): {
|
|
15
107
|
registry: {
|
|
@@ -20,7 +112,7 @@ export declare class Constellation extends RequestClient {
|
|
|
20
112
|
catalog: Json;
|
|
21
113
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
22
114
|
applyChanges: (changes: Json[], signal?: AbortSignal) => Promise<Json>;
|
|
23
|
-
listHistory: (kind: string, id: string, query?:
|
|
115
|
+
listHistory: (kind: string, id: string, query?: PaginationQuery, signal?: AbortSignal) => Promise<Page<Json>>;
|
|
24
116
|
rollback: (kind: string, id: string, input: {
|
|
25
117
|
toVersion: number;
|
|
26
118
|
expectedVersion: number;
|
|
@@ -32,62 +124,84 @@ export declare class Constellation extends RequestClient {
|
|
|
32
124
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
33
125
|
};
|
|
34
126
|
};
|
|
35
|
-
/**
|
|
127
|
+
/** Request reads enforce key scope; global operational reads require an unscoped telemetry key. Metadata is the default. */
|
|
36
128
|
get telemetry(): {
|
|
37
129
|
requests: {
|
|
38
|
-
list: (query?:
|
|
39
|
-
get: (id: string,
|
|
40
|
-
getSummary: (id: string,
|
|
41
|
-
|
|
130
|
+
list: (query?: RequestListQuery & TelemetryQuery, signal?: AbortSignal) => Promise<TelemetryPage<TelemetryRequest>>;
|
|
131
|
+
get: (id: string, options?: TelemetryReadOptions) => Promise<TelemetryInspection>;
|
|
132
|
+
getSummary: (id: string, options?: TelemetryReadOptions) => Promise<TelemetryInspection>;
|
|
133
|
+
getTimings: (id: string, signal?: AbortSignal) => Promise<RequestTimings>;
|
|
134
|
+
listEvents: (id: string, after?: number, options?: TelemetryReadOptions) => Promise<{
|
|
42
135
|
items: RequestEvent[];
|
|
136
|
+
metadataOnly?: true;
|
|
43
137
|
}>;
|
|
44
|
-
listRecords: <K extends keyof RecordTypes>(id: string, kind: K, query?:
|
|
45
|
-
getTimeline: (id: string, options?: {
|
|
138
|
+
listRecords: <K extends keyof RecordTypes>(id: string, kind: K, query?: RequestRecordsQuery & TelemetryQuery, signal?: AbortSignal) => Promise<TelemetryPage<TelemetryRecords[K]>>;
|
|
139
|
+
getTimeline: (id: string, options?: TelemetryReadOptions & {
|
|
46
140
|
requestId?: string;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
getHttpBody: (id: string, attemptId: string, query: {
|
|
141
|
+
}) => Promise<TelemetryTimeline>;
|
|
142
|
+
getHttpExchange: (id: string, attemptId: string, options?: TelemetryReadOptions & PaginationQuery) => Promise<Json>;
|
|
143
|
+
getHttpBody: (id: string, attemptId: string, query: TelemetryQuery & {
|
|
51
144
|
direction: "request" | "response";
|
|
52
145
|
offset?: number;
|
|
53
146
|
limit?: number;
|
|
54
147
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
55
148
|
};
|
|
56
149
|
system: {
|
|
57
|
-
get: (
|
|
58
|
-
listHistory: (query?: {
|
|
150
|
+
get: (options?: TelemetryReadOptions) => Promise<Json>;
|
|
151
|
+
listHistory: (query?: TelemetryQuery & {
|
|
59
152
|
hours?: 1 | 24 | 168;
|
|
60
153
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
61
|
-
getComponent: (component: string,
|
|
154
|
+
getComponent: (component: string, options?: TelemetryReadOptions & OperationsQuery) => Promise<Json>;
|
|
62
155
|
};
|
|
63
156
|
observability: {
|
|
64
|
-
get: (query?:
|
|
65
|
-
getSeries: (query: {
|
|
66
|
-
source: "local" | "gateway";
|
|
157
|
+
get: (query?: ObservabilityQuery & TelemetryQuery, signal?: AbortSignal) => Promise<Json>;
|
|
158
|
+
getSeries: (query: TelemetryQuery & {
|
|
67
159
|
hours?: 1 | 24 | 168;
|
|
68
|
-
providerId?: string;
|
|
69
160
|
modelId?: string;
|
|
161
|
+
} & ({
|
|
162
|
+
source: "local";
|
|
163
|
+
providerId?: string;
|
|
164
|
+
upstream?: never;
|
|
165
|
+
} | {
|
|
166
|
+
source: "gateway";
|
|
167
|
+
upstream?: string;
|
|
168
|
+
providerId?: never;
|
|
169
|
+
}), signal?: AbortSignal) => Promise<Json>;
|
|
170
|
+
getTiming: (query?: TelemetryQuery & {
|
|
171
|
+
hours?: 1 | 24 | 168;
|
|
70
172
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
71
|
-
|
|
173
|
+
getTraffic: (query?: TelemetryQuery & {
|
|
72
174
|
hours?: 1 | 24 | 168;
|
|
73
175
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
176
|
+
getBilling: (query?: PaginationQuery & TelemetryQuery & {
|
|
177
|
+
hours?: 1 | 24 | 168 | 720;
|
|
178
|
+
providerId?: string;
|
|
179
|
+
modelId?: string;
|
|
180
|
+
groupBy?: "provider" | "model";
|
|
181
|
+
}, signal?: AbortSignal) => Promise<Json>;
|
|
74
182
|
};
|
|
75
183
|
jobs: {
|
|
76
|
-
listHistory: (query?:
|
|
184
|
+
listHistory: (query?: OperationsQuery & TelemetryQuery, signal?: AbortSignal) => Promise<Json>;
|
|
77
185
|
};
|
|
78
186
|
notifications: {
|
|
79
|
-
list: (query?:
|
|
187
|
+
list: (query?: TelemetryQuery & {
|
|
188
|
+
offset?: number;
|
|
80
189
|
status?: "active" | "resolved";
|
|
81
|
-
}, signal?: AbortSignal) => Promise<
|
|
82
|
-
get: (id: string, query?:
|
|
83
|
-
|
|
190
|
+
}, signal?: AbortSignal) => Promise<Json>;
|
|
191
|
+
get: (id: string, query?: TelemetryQuery & {
|
|
192
|
+
offset?: number;
|
|
193
|
+
}, signal?: AbortSignal) => Promise<Json>;
|
|
194
|
+
listEvents: (query?: TelemetryQuery & {
|
|
84
195
|
after?: number;
|
|
85
196
|
}, signal?: AbortSignal) => Promise<Json>;
|
|
86
197
|
};
|
|
87
198
|
logs: {
|
|
88
|
-
searchSystem: (query?:
|
|
89
|
-
searchRequests: (query?:
|
|
90
|
-
|
|
199
|
+
searchSystem: (query?: LogSearchQuery & TelemetryQuery, signal?: AbortSignal) => Promise<Page<Json>>;
|
|
200
|
+
searchRequests: (query?: Omit<LogSearchQuery, "level" | "levelNot" | "target" | "targetNot"> & {
|
|
201
|
+
level?: "debug" | "info" | "warn" | "error";
|
|
202
|
+
levelNot?: "debug" | "info" | "warn" | "error";
|
|
203
|
+
} & TelemetryQuery, signal?: AbortSignal) => Promise<Page<Json>>;
|
|
204
|
+
searchAudit: (query?: Omit<LogSearchQuery, "requestId" | "requestIdNot"> & TelemetryQuery, signal?: AbortSignal) => Promise<Page<Json>>;
|
|
91
205
|
};
|
|
92
206
|
};
|
|
93
207
|
get webhooks(): {
|