@lionhummer/constellation 0.2.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.
@@ -0,0 +1,6 @@
1
+ /** Error telemetry deliberately omits stack traces and arbitrary object fields. */
2
+ export declare function callerErrorDetails(error: unknown): {
3
+ name: string;
4
+ message: string;
5
+ code?: string;
6
+ };
@@ -1,4 +1,4 @@
1
- /** Durable request client. No provider credentials or application policy live here. */
1
+ /** Shared execution wire types and client mechanics. Authentication belongs to each client. */
2
2
  export type Json = null | boolean | number | string | Json[] | {
3
3
  [key: string]: Json;
4
4
  };
@@ -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,106 +330,102 @@ export declare class ConstellationError extends Error {
327
330
  constructor(status: number, code: string, message: string);
328
331
  }
329
332
  export declare function uuid7(): string;
330
- export declare class Constellation {
331
- private options;
332
- private fetcher;
333
- constructor(options: {
334
- baseUrl: string;
335
- apiKey?: string;
336
- apiPrefix?: "/v1" | "/internal";
337
- fetch?: typeof fetch;
338
- timeoutMs?: number;
339
- });
340
- private url;
341
- private call;
342
- submit(input: RequestInput, signal?: AbortSignal): Promise<{
343
- id: string;
344
- }>;
345
- inspect(id: string, signal?: AbortSignal): Promise<Inspection>;
346
- /** Canonical API timeline shared with the console. Derived rows disclose their timestamp basis. */
347
- timeline(id: string, options?: {
348
- requestId?: string;
349
- signal?: AbortSignal;
350
- }): Promise<Timeline>;
351
- /** Request context without loading historical telemetry. Fetch records by page. */
352
- inspectSummary(id: string, signal?: AbortSignal): Promise<Inspection>;
353
- records<K extends keyof RecordTypes>(id: string, kind: K, query?: {
354
- id?: string;
355
- q?: string;
356
- level?: Log["level"];
357
- offset?: number;
358
- limit?: number;
359
- }, signal?: AbortSignal): Promise<{
360
- items: RecordTypes[K][];
361
- total: number;
362
- offset: number;
363
- limit: number;
364
- }>;
365
- resolve(input: RequestInput, signal?: AbortSignal): Promise<{
366
- revision: number;
367
- resolution: Record<string, Json>;
368
- rules: Record<string, Json>;
369
- allowed: boolean;
370
- dispatched: false;
371
- }>;
372
- list(query?: {
373
- q?: string;
374
- requestId?: string;
375
- requestIdNot?: string;
376
- externalId?: string;
377
- externalIdNot?: string;
378
- externalIdContains?: string;
379
- externalIdNotContains?: string;
380
- workspaceId?: string;
381
- workspaceIdNot?: string;
382
- userId?: string;
383
- userIdNot?: string;
384
- status?: Status;
385
- statusNot?: Status;
386
- requestedModel?: string;
387
- requestedModelNot?: string;
388
- requestedModelContains?: string;
389
- requestedModelNotContains?: string;
390
- limit?: number;
391
- offset?: number;
392
- }, signal?: AbortSignal): Promise<{
393
- items: RequestRecord[];
394
- total: number;
395
- offset: number;
396
- limit: number;
397
- }>;
398
- cancel(id: string, signal?: AbortSignal): Promise<void>;
399
- claim(id: string, inputId: string, claimId: string, signal?: AbortSignal): Promise<void>;
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
+ };
382
+ export type RequestRecordsQuery = {
383
+ id?: string;
384
+ q?: string;
385
+ level?: Log["level"];
386
+ offset?: number;
387
+ limit?: number;
388
+ };
389
+ export type RequestListQuery = {
390
+ q?: string;
391
+ requestId?: string;
392
+ requestIdNot?: string;
393
+ externalId?: string;
394
+ externalIdNot?: string;
395
+ externalIdContains?: string;
396
+ externalIdNotContains?: string;
397
+ workspaceId?: string;
398
+ workspaceIdNot?: string;
399
+ userId?: string;
400
+ userIdNot?: string;
401
+ status?: Status;
402
+ statusNot?: Status;
403
+ requestedModel?: string;
404
+ requestedModelNot?: string;
405
+ requestedModelContains?: string;
406
+ requestedModelNotContains?: string;
407
+ limit?: number;
408
+ offset?: number;
409
+ };
410
+ export type StartSpanOptions = {
411
+ stepId?: string;
412
+ attemptId?: string;
413
+ inputId?: string;
414
+ parentSpanId?: string;
415
+ startedAt?: string;
416
+ attributes?: Record<string, Json>;
417
+ };
418
+ type ClientOptions = {
419
+ baseUrl: string;
420
+ apiPrefix?: "/v1" | "/internal";
421
+ fetch?: typeof fetch;
422
+ timeoutMs?: number;
423
+ };
424
+ export declare class RequestClient {
425
+ #private;
426
+ constructor(options: ClientOptions);
400
427
  /** Agent claims are leases. Keep one alive while a caller handler is running. */
401
428
  private maintainClaim;
402
- private whileClaimed;
403
- respond(id: string, inputId: string, response: InputResponse, signal?: AbortSignal): Promise<void>;
404
- addSpans(id: string, spans: Span[], signal?: AbortSignal): Promise<void>;
405
- addLogs(id: string, logs: Log[], signal?: AbortSignal): Promise<void>;
406
- startSpan(id: string, name: string, options?: {
407
- stepId?: string;
408
- attemptId?: string;
409
- inputId?: string;
410
- parentSpanId?: string;
411
- startedAt?: string;
412
- attributes?: Record<string, Json>;
413
- }, signal?: AbortSignal): Promise<{
414
- id: string;
415
- end: (options?: {
416
- endedAt?: string;
417
- status?: "ok" | "error" | "cancelled";
418
- attributes?: Record<string, Json>;
419
- }, signal?: AbortSignal) => Promise<void>;
420
- }>;
421
- /** Live SSE delivery with durable cursor replay after disconnects. */
422
- events(id: string, options?: {
423
- after?: number;
424
- signal?: AbortSignal;
425
- }): AsyncGenerator<RequestEvent>;
426
- /** Process one delivered input and exit. An input notification can be retried safely. */
427
- private handleInput;
428
- /** Handle pending inputs until the request ends. */
429
- private processInputs;
430
429
  /** Client-safe discovery with an execution key. */
431
430
  get models(): {
432
431
  list: (scope: ModelScope, signal?: AbortSignal) => Promise<Json>;
@@ -446,7 +445,8 @@ export declare class Constellation {
446
445
  }>;
447
446
  get: (id: string, signal?: AbortSignal) => Promise<Inspection>;
448
447
  getSummary: (id: string, signal?: AbortSignal) => Promise<Inspection>;
449
- list: (query?: Parameters<Constellation["list"]>[0], signal?: AbortSignal) => Promise<{
448
+ getTimings: (id: string, signal?: AbortSignal) => Promise<RequestTimings>;
449
+ list: (query?: RequestListQuery, signal?: AbortSignal) => Promise<{
450
450
  items: RequestRecord[];
451
451
  total: number;
452
452
  offset: number;
@@ -460,7 +460,7 @@ export declare class Constellation {
460
460
  after?: number;
461
461
  signal?: AbortSignal;
462
462
  }) => AsyncGenerator<RequestEvent, any, any>;
463
- listRecords: <K extends keyof RecordTypes>(id: string, kind: K, query?: Parameters<Constellation["records"]>[2], signal?: AbortSignal) => Promise<{
463
+ listRecords: <K extends keyof RecordTypes>(id: string, kind: K, query?: RequestRecordsQuery, signal?: AbortSignal) => Promise<{
464
464
  items: RecordTypes[K][];
465
465
  total: number;
466
466
  offset: number;
@@ -470,7 +470,10 @@ export declare class Constellation {
470
470
  requestId?: string;
471
471
  signal?: AbortSignal;
472
472
  }) => Promise<Timeline>;
473
- getHttpExchange: (id: string, attemptId: string, signal?: AbortSignal) => Promise<Json>;
473
+ getHttpExchange: (id: string, attemptId: string, query?: {
474
+ offset?: number;
475
+ limit?: number;
476
+ }, signal?: AbortSignal) => Promise<Json>;
474
477
  getHttpBody: (id: string, attemptId: string, query: {
475
478
  direction: "request" | "response";
476
479
  offset?: number;
@@ -485,7 +488,7 @@ export declare class Constellation {
485
488
  respond: (requestId: string, inputId: string, response: InputResponse, signal?: AbortSignal) => Promise<void>;
486
489
  };
487
490
  get spans(): {
488
- start: (requestId: string, name: string, options?: Parameters<Constellation["startSpan"]>[2], signal?: AbortSignal) => Promise<{
491
+ start: (requestId: string, name: string, options?: StartSpanOptions, signal?: AbortSignal) => Promise<{
489
492
  id: string;
490
493
  end: (options?: {
491
494
  endedAt?: string;
@@ -498,114 +501,5 @@ export declare class Constellation {
498
501
  get logs(): {
499
502
  add: (requestId: string, logs: Log[], signal?: AbortSignal) => Promise<void>;
500
503
  };
501
- /** Configuration endpoints require a management key. */
502
- get management(): {
503
- registry: {
504
- get: (signal?: AbortSignal) => Promise<Json>;
505
- listRows: (kind: "models" | "providers" | "plans" | "rules", query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
506
- update: (input: {
507
- expectedRevision: number;
508
- catalog: Json;
509
- }, signal?: AbortSignal) => Promise<Json>;
510
- applyChanges: (changes: Json[], signal?: AbortSignal) => Promise<Json>;
511
- listHistory: (kind: string, id: string, query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
512
- rollback: (kind: string, id: string, input: {
513
- toVersion: number;
514
- expectedVersion: number;
515
- }, signal?: AbortSignal) => Promise<Json>;
516
- preview: (input: ModelResolution, signal?: AbortSignal) => Promise<Json>;
517
- testRules: (scope: {
518
- workspaceId: string;
519
- userId?: string;
520
- }, signal?: AbortSignal) => Promise<Json>;
521
- };
522
- keys: {
523
- list: (signal?: AbortSignal) => Promise<Json>;
524
- listPage: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
525
- create: (input: Json, signal?: AbortSignal) => Promise<Json>;
526
- revoke: (id: string, signal?: AbortSignal) => Promise<void>;
527
- setInputWebhook: (id: string, input: {
528
- url: string | null;
529
- token?: string;
530
- }, signal?: AbortSignal) => Promise<Json>;
531
- };
532
- credentials: {
533
- list: (signal?: AbortSignal) => Promise<Json>;
534
- listPage: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
535
- create: (input: Json, signal?: AbortSignal) => Promise<Json>;
536
- update: (ref: string, input: Json, signal?: AbortSignal) => Promise<void>;
537
- delete: (ref: string, signal?: AbortSignal) => Promise<void>;
538
- };
539
- executionSettings: {
540
- get: (signal?: AbortSignal) => Promise<Json>;
541
- update: (input: Json, signal?: AbortSignal) => Promise<Json>;
542
- listHistory: (signal?: AbortSignal) => Promise<Json>;
543
- };
544
- };
545
- /** Read-only operational endpoints require a telemetry key. */
546
- get telemetry(): {
547
- requests: {
548
- list: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<RequestRecord>>;
549
- get: (id: string, signal?: AbortSignal) => Promise<Inspection>;
550
- getSummary: (id: string, signal?: AbortSignal) => Promise<Inspection>;
551
- listEvents: (id: string, after?: number, signal?: AbortSignal) => Promise<{
552
- items: RequestEvent[];
553
- }>;
554
- listRecords: <K extends keyof RecordTypes>(id: string, kind: K, query?: PageQuery, signal?: AbortSignal) => Promise<Page<RecordTypes[K]>>;
555
- getTimeline: (id: string, options?: {
556
- requestId?: string;
557
- signal?: AbortSignal;
558
- }) => Promise<Timeline>;
559
- getHttpExchange: (id: string, attemptId: string, signal?: AbortSignal) => Promise<Json>;
560
- getHttpBody: (id: string, attemptId: string, query: {
561
- direction: "request" | "response";
562
- offset?: number;
563
- limit?: number;
564
- }, signal?: AbortSignal) => Promise<Json>;
565
- };
566
- system: {
567
- get: (signal?: AbortSignal) => Promise<Json>;
568
- listHistory: (query?: {
569
- hours?: 1 | 24 | 168;
570
- }, signal?: AbortSignal) => Promise<Json>;
571
- getComponent: (component: string, signal?: AbortSignal) => Promise<Json>;
572
- };
573
- observability: {
574
- get: (query?: PageQuery, signal?: AbortSignal) => Promise<Json>;
575
- getSeries: (query: {
576
- source: "local" | "gateway";
577
- hours?: 1 | 24 | 168;
578
- providerId?: string;
579
- modelId?: string;
580
- }, signal?: AbortSignal) => Promise<Json>;
581
- getTiming: (query?: {
582
- hours?: 1 | 24 | 168;
583
- }, signal?: AbortSignal) => Promise<Json>;
584
- };
585
- jobs: {
586
- listHistory: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
587
- };
588
- notifications: {
589
- list: (query?: PageQuery & {
590
- status?: "active" | "resolved";
591
- }, signal?: AbortSignal) => Promise<Page<Json>>;
592
- get: (id: string, query?: PageQuery, signal?: AbortSignal) => Promise<Json>;
593
- listEvents: (query?: {
594
- after?: number;
595
- }, signal?: AbortSignal) => Promise<Json>;
596
- };
597
- logs: {
598
- searchSystem: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
599
- searchRequests: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
600
- searchAudit: (query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
601
- };
602
- };
603
- get health(): {
604
- live: (signal?: AbortSignal) => Promise<Json>;
605
- ready: (signal?: AbortSignal) => Promise<Json>;
606
- };
607
- get webhooks(): {
608
- verify: (request: Request, expectedToken: string) => Promise<WebhookEvent>;
609
- };
610
504
  }
611
505
  export {};
@@ -0,0 +1,210 @@
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 RequestEvent, type RecordTypes, type Timeline, type TimelineRow, type RequestListQuery, type RequestRecordsQuery, type RequestTimings, type TokenUsage } from "../../client-core/src/index";
3
+ export { ConstellationError, uuid7 } 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
+ };
95
+ export declare class Constellation extends RequestClient {
96
+ #private;
97
+ constructor(options: {
98
+ baseUrl: string;
99
+ apiKey: string;
100
+ fetch?: typeof fetch;
101
+ timeoutMs?: number;
102
+ });
103
+ /** Discover HTTP operations available to this bearer key. */
104
+ discover(signal?: AbortSignal): Promise<DiscoveryDocument>;
105
+ /** Registry authoring only; keys, credentials and capacity controls are internal. */
106
+ get management(): {
107
+ registry: {
108
+ get: (signal?: AbortSignal) => Promise<Json>;
109
+ listRows: (kind: "models" | "providers" | "plans" | "rules", query?: PageQuery, signal?: AbortSignal) => Promise<Page<Json>>;
110
+ update: (input: {
111
+ expectedRevision: number;
112
+ catalog: Json;
113
+ }, signal?: AbortSignal) => Promise<Json>;
114
+ applyChanges: (changes: Json[], signal?: AbortSignal) => Promise<Json>;
115
+ listHistory: (kind: string, id: string, query?: PaginationQuery, signal?: AbortSignal) => Promise<Page<Json>>;
116
+ rollback: (kind: string, id: string, input: {
117
+ toVersion: number;
118
+ expectedVersion: number;
119
+ }, signal?: AbortSignal) => Promise<Json>;
120
+ preview: (input: ModelResolution, signal?: AbortSignal) => Promise<Json>;
121
+ testRules: (scope: {
122
+ workspaceId: string;
123
+ userId?: string;
124
+ }, signal?: AbortSignal) => Promise<Json>;
125
+ };
126
+ };
127
+ /** Request reads enforce key scope; global operational reads require an unscoped telemetry key. Metadata is the default. */
128
+ get telemetry(): {
129
+ requests: {
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<{
135
+ items: RequestEvent[];
136
+ metadataOnly?: true;
137
+ }>;
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 & {
140
+ requestId?: string;
141
+ }) => Promise<TelemetryTimeline>;
142
+ getHttpExchange: (id: string, attemptId: string, options?: TelemetryReadOptions & PaginationQuery) => Promise<Json>;
143
+ getHttpBody: (id: string, attemptId: string, query: TelemetryQuery & {
144
+ direction: "request" | "response";
145
+ offset?: number;
146
+ limit?: number;
147
+ }, signal?: AbortSignal) => Promise<Json>;
148
+ };
149
+ system: {
150
+ get: (options?: TelemetryReadOptions) => Promise<Json>;
151
+ listHistory: (query?: TelemetryQuery & {
152
+ hours?: 1 | 24 | 168;
153
+ }, signal?: AbortSignal) => Promise<Json>;
154
+ getComponent: (component: string, options?: TelemetryReadOptions & OperationsQuery) => Promise<Json>;
155
+ };
156
+ observability: {
157
+ get: (query?: ObservabilityQuery & TelemetryQuery, signal?: AbortSignal) => Promise<Json>;
158
+ getSeries: (query: TelemetryQuery & {
159
+ hours?: 1 | 24 | 168;
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;
172
+ }, signal?: AbortSignal) => Promise<Json>;
173
+ getTraffic: (query?: TelemetryQuery & {
174
+ hours?: 1 | 24 | 168;
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>;
182
+ };
183
+ jobs: {
184
+ listHistory: (query?: OperationsQuery & TelemetryQuery, signal?: AbortSignal) => Promise<Json>;
185
+ };
186
+ notifications: {
187
+ list: (query?: TelemetryQuery & {
188
+ offset?: number;
189
+ status?: "active" | "resolved";
190
+ }, signal?: AbortSignal) => Promise<Json>;
191
+ get: (id: string, query?: TelemetryQuery & {
192
+ offset?: number;
193
+ }, signal?: AbortSignal) => Promise<Json>;
194
+ listEvents: (query?: TelemetryQuery & {
195
+ after?: number;
196
+ }, signal?: AbortSignal) => Promise<Json>;
197
+ };
198
+ logs: {
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>>;
205
+ };
206
+ };
207
+ get webhooks(): {
208
+ verify: (request: Request, expectedToken: string) => Promise<WebhookEvent>;
209
+ };
210
+ }
@@ -0,0 +1,48 @@
1
+ import { Constellation, uuid7 } from "@lionhummer/constellation";
2
+
3
+ function required(name) {
4
+ const value = process.env[name];
5
+ if (!value) throw new Error(`Set ${name} in your server environment.`);
6
+ return value;
7
+ }
8
+
9
+ const workspaceId = required("CONSTELLATION_WORKSPACE_ID");
10
+ const userId = process.env.CONSTELLATION_USER_ID || undefined;
11
+ const planId = process.env.CONSTELLATION_PLAN_ID || undefined;
12
+ const client = new Constellation({
13
+ baseUrl: required("CONSTELLATION_BASE_URL"),
14
+ apiKey: required("CONSTELLATION_EXECUTION_KEY"),
15
+ });
16
+
17
+ // Discovery uses the same scope as execution. It does not call a provider.
18
+ const catalog = await client.models.list({ workspaceId, userId, planId });
19
+ console.log("Available models:", JSON.stringify(catalog, null, 2));
20
+ const model = process.env.CONSTELLATION_MODEL;
21
+ if (!model) {
22
+ console.log("Set CONSTELLATION_MODEL to one of the returned models[].id values, then rerun.");
23
+ } else {
24
+ const input = {
25
+ idempotencyKey: uuid7(), // Save this input/key if submission needs retrying.
26
+ workspaceId,
27
+ userId,
28
+ planId,
29
+ model,
30
+ messages: [{ role: "user", text: "Say hello in one short sentence." }],
31
+ maxOutputTokens: 256,
32
+ timeoutMs: 120_000,
33
+ // No tools or wait checkpoints: no webhook or input consumer is needed.
34
+ };
35
+ const { id } = await client.requests.create(input);
36
+ console.log("Request ID:", id);
37
+ for await (const event of client.requests.streamEvents(id, {
38
+ signal: AbortSignal.timeout(150_000),
39
+ })) {
40
+ console.log(event.seq, event.type);
41
+ }
42
+ const { request } = await client.requests.getSummary(id);
43
+ console.log("Final status:", request.status);
44
+ console.log("Output:", request.output?.text ?? "");
45
+ if (request.status !== "completed") {
46
+ throw new Error(`Request ${id} ended as ${request.status}: ${request.reason ?? "inspect the request error and attempts"}`);
47
+ }
48
+ }