@ancplua/qyl-api-schema 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.
Files changed (54) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +89 -0
  3. package/VERSIONING.md +74 -0
  4. package/api/routes.tsp +1052 -0
  5. package/api/streaming.tsp +335 -0
  6. package/common/errors.tsp +206 -0
  7. package/common/pagination.tsp +254 -0
  8. package/common/types.tsp +345 -0
  9. package/generated/README.md +26 -0
  10. package/generated/otel-keys.gen.tsp +1648 -0
  11. package/index.tsp +55 -0
  12. package/intelligence/causal-rules.tsp +34 -0
  13. package/intelligence/diagnostic-patterns.tsp +54 -0
  14. package/intelligence/investigation-strategies.tsp +37 -0
  15. package/intelligence/main.tsp +19 -0
  16. package/intelligence/seed/patterns.tsp +172 -0
  17. package/intelligence/seed/rules.tsp +44 -0
  18. package/intelligence/seed/strategies.tsp +56 -0
  19. package/intelligence/signals.tsp +60 -0
  20. package/models/agent/agent-run.tsp +154 -0
  21. package/models/agent/tool-call.tsp +122 -0
  22. package/models/agent/workflow-checkpoint.tsp +50 -0
  23. package/models/agent/workflow-execution.tsp +136 -0
  24. package/models/alerting.tsp +436 -0
  25. package/models/configurator.tsp +433 -0
  26. package/models/control-graph.tsp +197 -0
  27. package/models/db.tsp +810 -0
  28. package/models/deployment.tsp +365 -0
  29. package/models/error.tsp +433 -0
  30. package/models/genai.tsp +1368 -0
  31. package/models/http.tsp +600 -0
  32. package/models/identity.tsp +213 -0
  33. package/models/issues.tsp +484 -0
  34. package/models/log.tsp +140 -0
  35. package/models/messaging.tsp +304 -0
  36. package/models/otel-config.tsp +455 -0
  37. package/models/retention.tsp +240 -0
  38. package/models/rpc.tsp +309 -0
  39. package/models/search.tsp +243 -0
  40. package/models/session.tsp +274 -0
  41. package/models/system.tsp +400 -0
  42. package/models/test.tsp +346 -0
  43. package/models/triage.tsp +113 -0
  44. package/models/workflow.tsp +396 -0
  45. package/models/workspace.tsp +435 -0
  46. package/otel/enums.tsp +392 -0
  47. package/otel/logs.tsp +135 -0
  48. package/otel/metrics.tsp +358 -0
  49. package/otel/otel-conventions.tsp +14 -0
  50. package/otel/profiles.tsp +335 -0
  51. package/otel/resource.tsp +257 -0
  52. package/otel/span.tsp +307 -0
  53. package/package.json +88 -0
  54. package/tspconfig.yaml +49 -0
@@ -0,0 +1,335 @@
1
+ // =============================================================================
2
+ // qyl streaming API routes
3
+ // =============================================================================
4
+ // Server-Sent Events (SSE) streaming endpoints for real-time telemetry.
5
+ // =============================================================================
6
+
7
+ import "@typespec/http";
8
+ import "@typespec/sse";
9
+ import "@typespec/events";
10
+ import "@typespec/versioning";
11
+
12
+ import "../common/types.tsp";
13
+ import "../common/pagination.tsp";
14
+ import "../otel/span.tsp";
15
+ import "../otel/logs.tsp";
16
+ import "../otel/metrics.tsp";
17
+ import "../models/deployment.tsp";
18
+
19
+ using TypeSpec.Http;
20
+ using TypeSpec.SSE;
21
+ using TypeSpec.Events;
22
+ using TypeSpec.Versioning;
23
+
24
+ using Qyl.Api.Contracts.Common;
25
+ using Qyl.Api.Contracts.OTel.Traces;
26
+ using Qyl.Api.Contracts.OTel.Logs;
27
+ using Qyl.Api.Contracts.OTel.Metrics;
28
+ using Qyl.Api.Contracts.OTel.Enums;
29
+ using Qyl.Api.Contracts.Domains.Ops.Deployment;
30
+
31
+ namespace Qyl.Api.Contracts.Streaming;
32
+
33
+ // =============================================================================
34
+ // Stream Event Types
35
+ // =============================================================================
36
+
37
+ @doc("Trace stream event")
38
+ model TraceStreamEvent {
39
+ @doc("Event type")
40
+ type: "trace";
41
+
42
+ @doc("Trace data")
43
+ data: Trace;
44
+
45
+ @doc("Event timestamp")
46
+ timestamp: utcDateTime;
47
+ }
48
+
49
+ @doc("Span stream event")
50
+ model SpanStreamEvent {
51
+ @doc("Event type")
52
+ type: "span";
53
+
54
+ @doc("Span data")
55
+ data: Span;
56
+
57
+ @doc("Event timestamp")
58
+ timestamp: utcDateTime;
59
+ }
60
+
61
+ @doc("Log stream event")
62
+ model LogStreamEvent {
63
+ @doc("Event type")
64
+ type: "log";
65
+
66
+ @doc("Log data")
67
+ data: LogRecord;
68
+
69
+ @doc("Event timestamp")
70
+ timestamp: utcDateTime;
71
+ }
72
+
73
+ @doc("Metric stream event")
74
+ model MetricStreamEvent {
75
+ @doc("Event type")
76
+ type: "metric";
77
+
78
+ @doc("Metric data")
79
+ data: Metric;
80
+
81
+ @doc("Event timestamp")
82
+ timestamp: utcDateTime;
83
+ }
84
+
85
+ @doc("Deployment stream event")
86
+ model DeploymentStreamEvent {
87
+ @doc("Event type")
88
+ type: "deployment";
89
+
90
+ @doc("Deployment event data")
91
+ data: DeploymentEvent;
92
+
93
+ @doc("Event timestamp")
94
+ timestamp: utcDateTime;
95
+ }
96
+
97
+ @doc("Heartbeat event for connection keep-alive")
98
+ model HeartbeatEvent {
99
+ @doc("Event type")
100
+ type: "heartbeat";
101
+
102
+ @doc("Server timestamp")
103
+ timestamp: utcDateTime;
104
+ }
105
+
106
+ // =============================================================================
107
+ // Combined Stream Event Union
108
+ // =============================================================================
109
+
110
+ @doc("All possible stream event types")
111
+ @events
112
+ union TelemetryStreamEvent {
113
+ trace: TraceStreamEvent,
114
+ span: SpanStreamEvent,
115
+ log: LogStreamEvent,
116
+ metric: MetricStreamEvent,
117
+ deployment: DeploymentStreamEvent,
118
+ heartbeat: HeartbeatEvent,
119
+ }
120
+
121
+ @doc("Trace stream events")
122
+ @events
123
+ union TraceEvents {
124
+ trace: TraceStreamEvent,
125
+ heartbeat: HeartbeatEvent,
126
+ }
127
+
128
+ @doc("Span stream events")
129
+ @events
130
+ union SpanEvents {
131
+ span: SpanStreamEvent,
132
+ heartbeat: HeartbeatEvent,
133
+ }
134
+
135
+ @doc("Log stream events")
136
+ @events
137
+ union LogEvents {
138
+ log: LogStreamEvent,
139
+ heartbeat: HeartbeatEvent,
140
+ }
141
+
142
+ @doc("Metric stream events")
143
+ @events
144
+ union MetricEvents {
145
+ metric: MetricStreamEvent,
146
+ heartbeat: HeartbeatEvent,
147
+ }
148
+
149
+ @doc("Deployment stream events")
150
+ @events
151
+ union DeploymentEvents {
152
+ deployment: DeploymentStreamEvent,
153
+ heartbeat: HeartbeatEvent,
154
+ }
155
+
156
+ // =============================================================================
157
+ // Stream Subscription Models
158
+ // =============================================================================
159
+
160
+ @doc("Stream subscription request")
161
+ model StreamSubscription {
162
+ @doc("Event types to subscribe to")
163
+ @encodedName("application/json", "event_types")
164
+ eventTypes: StreamEventType[];
165
+
166
+ @doc("Service name filter")
167
+ @encodedName("application/json", "service_name")
168
+ serviceName?: string;
169
+
170
+ @doc("Trace ID filter (for specific trace)")
171
+ @encodedName("application/json", "trace_id")
172
+ traceId?: TraceId;
173
+
174
+ @doc("Minimum severity for logs (1-24)")
175
+ @encodedName("application/json", "min_severity")
176
+ @minValue(1)
177
+ @maxValue(24)
178
+ minSeverity?: int32;
179
+
180
+ @doc("Attribute filters")
181
+ filters?: Record<string>;
182
+
183
+ @doc("Sample rate (0.0-1.0)")
184
+ @encodedName("application/json", "sample_rate")
185
+ @minValue(0)
186
+ @maxValue(1)
187
+ sampleRate?: float64;
188
+ }
189
+
190
+ @doc("Stream event types")
191
+ enum StreamEventType {
192
+ @doc("Trace events")
193
+ traces: "traces",
194
+
195
+ @doc("Span events")
196
+ spans: "spans",
197
+
198
+ @doc("Log events")
199
+ logs: "logs",
200
+
201
+ @doc("Metric events")
202
+ metrics: "metrics",
203
+
204
+ @doc("Deployment events")
205
+ deployments: "deployments",
206
+
207
+ @doc("All events")
208
+ all: "all",
209
+ }
210
+
211
+ // =============================================================================
212
+ // Streaming API Interfaces
213
+ // =============================================================================
214
+
215
+ @route("/api/v1/stream")
216
+ @tag("Streaming")
217
+ interface StreamingApi {
218
+ @doc("Stream all telemetry events (SSE)")
219
+ @get
220
+ @route("/events")
221
+ streamEvents(
222
+ @query @doc("Event types") types?: StreamEventType[],
223
+ @query @doc("Service name filter") serviceName?: string,
224
+ @query @doc("Sample rate") sampleRate?: float64,
225
+ ): SSEStream<TelemetryStreamEvent>;
226
+
227
+ @doc("Stream traces in real-time")
228
+ @get
229
+ @route("/traces")
230
+ streamTraces(
231
+ @query @doc("Service name filter") serviceName?: string,
232
+ @query @doc("Minimum duration filter") minDurationMs?: int64,
233
+ ): SSEStream<TraceEvents>;
234
+
235
+ @doc("Stream spans for a specific trace")
236
+ @get
237
+ @route("/traces/{traceId}/spans")
238
+ streamTraceSpans(@path traceId: TraceId): SSEStream<SpanEvents>;
239
+
240
+ @doc("Stream logs in real-time")
241
+ @get
242
+ @route("/logs")
243
+ streamLogs(
244
+ @query @doc("Service name filter") serviceName?: string,
245
+ @query @doc("Minimum severity") minSeverity?: int32,
246
+ @query @doc("Query filter") query?: string,
247
+ ): SSEStream<LogEvents>;
248
+
249
+ @doc("Stream metrics in real-time")
250
+ @get
251
+ @route("/metrics")
252
+ streamMetrics(
253
+ @query @doc("Metric name filter") metricName?: string,
254
+ @query @doc("Service name filter") serviceName?: string,
255
+ ): SSEStream<MetricEvents>;
256
+
257
+ @doc("Stream deployment events")
258
+ @get
259
+ @route("/deployments")
260
+ streamDeployments(
261
+ @query @doc("Service name filter") serviceName?: string,
262
+ @query @doc("Environment filter") environment?: string,
263
+ ): SSEStream<DeploymentEvents>;
264
+ }
265
+
266
+ // =============================================================================
267
+ // WebSocket Streaming (Alternative)
268
+ // =============================================================================
269
+
270
+ @doc("WebSocket message wrapper")
271
+ model WebSocketMessage<T> {
272
+ @doc("Message ID")
273
+ id: string;
274
+
275
+ @doc("Message type")
276
+ type: WebSocketMessageType;
277
+
278
+ @doc("Message payload")
279
+ payload?: T;
280
+
281
+ @doc("Timestamp")
282
+ timestamp: utcDateTime;
283
+ }
284
+
285
+ @doc("WebSocket message types")
286
+ enum WebSocketMessageType {
287
+ @doc("Subscribe to events")
288
+ subscribe: "subscribe",
289
+
290
+ @doc("Unsubscribe from events")
291
+ unsubscribe: "unsubscribe",
292
+
293
+ @doc("Data event")
294
+ data: "data",
295
+
296
+ @doc("Error message")
297
+ error: "error",
298
+
299
+ @doc("Acknowledgment")
300
+ ack: "ack",
301
+
302
+ @doc("Ping")
303
+ ping: "ping",
304
+
305
+ @doc("Pong")
306
+ pong: "pong",
307
+ }
308
+
309
+ // =============================================================================
310
+ // Tail-based Sampling Configuration
311
+ // =============================================================================
312
+
313
+ @doc("Tail-based sampling configuration for streaming")
314
+ model TailSamplingConfig {
315
+ @doc("Enable tail-based sampling")
316
+ enabled: boolean;
317
+
318
+ @doc("Sample error traces")
319
+ @encodedName("application/json", "sample_errors")
320
+ sampleErrors: boolean;
321
+
322
+ @doc("Sample slow traces (above threshold)")
323
+ @encodedName("application/json", "sample_slow")
324
+ sampleSlow: boolean;
325
+
326
+ @doc("Slow trace threshold in milliseconds")
327
+ @encodedName("application/json", "slow_threshold_ms")
328
+ slowThresholdMs?: int64;
329
+
330
+ @doc("Random sample rate for remaining traces")
331
+ @encodedName("application/json", "random_rate")
332
+ @minValue(0)
333
+ @maxValue(1)
334
+ randomRate: float64;
335
+ }
@@ -0,0 +1,206 @@
1
+ // =============================================================================
2
+ // ANcpLua v2.0 - Error Models
3
+ // =============================================================================
4
+ // Standardized error responses following RFC 7807 Problem Details.
5
+ // =============================================================================
6
+
7
+ import "@typespec/http";
8
+
9
+ using TypeSpec.Http;
10
+
11
+ namespace Qyl.Api.Contracts.Common.Errors;
12
+
13
+ // =============================================================================
14
+ // RFC 7807 Problem Details Base
15
+ // =============================================================================
16
+
17
+ @doc("RFC 7807 Problem Details for HTTP APIs")
18
+ @error
19
+ model ProblemDetails {
20
+ @doc("A URI reference identifying the problem type")
21
+ @encodedName("application/json", "type")
22
+ problemType: url = "about:blank";
23
+
24
+ @doc("A short, human-readable summary of the problem type")
25
+ title: string;
26
+
27
+ @doc("The HTTP status code (informational only, actual code set by subtype)")
28
+ status: int32;
29
+
30
+ @doc("A human-readable explanation specific to this occurrence")
31
+ detail?: string;
32
+
33
+ @doc("A URI reference identifying the specific occurrence")
34
+ instance?: url;
35
+
36
+ @doc("Trace ID for correlation")
37
+ @encodedName("application/json", "trace_id")
38
+ @header("X-Trace-Id")
39
+ traceId?: string;
40
+
41
+ @doc("Request ID for support")
42
+ @encodedName("application/json", "request_id")
43
+ @header("X-Request-Id")
44
+ requestId?: string;
45
+
46
+ @doc("Timestamp of the error")
47
+ timestamp?: utcDateTime;
48
+ }
49
+
50
+ // =============================================================================
51
+ // Specific Error Types
52
+ // =============================================================================
53
+
54
+ @doc("Resource not found (404)")
55
+ @error
56
+ model NotFoundError extends ProblemDetails {
57
+ @statusCode _: 404;
58
+ title: "Not Found";
59
+
60
+ @doc("The type of resource that was not found")
61
+ @encodedName("application/json", "resource_type")
62
+ resourceType?: string;
63
+
64
+ @doc("The identifier that was not found")
65
+ @encodedName("application/json", "resource_id")
66
+ resourceId?: string;
67
+ }
68
+
69
+ @doc("Bad request - validation failed (400)")
70
+ @error
71
+ model ValidationError extends ProblemDetails {
72
+ @statusCode _: 400;
73
+ title: "Validation Failed";
74
+
75
+ @doc("List of validation errors")
76
+ errors: ValidationErrorDetail[];
77
+ }
78
+
79
+ @doc("Individual validation error detail")
80
+ model ValidationErrorDetail {
81
+ @doc("The field/property that failed validation")
82
+ field: string;
83
+
84
+ @doc("The error message")
85
+ message: string;
86
+
87
+ @doc("The validation rule that failed")
88
+ code: string;
89
+
90
+ @doc("The rejected value (if safe to include)")
91
+ @encodedName("application/json", "rejected_value")
92
+ rejectedValue?: string;
93
+ }
94
+
95
+ @doc("Unauthorized - authentication required (401)")
96
+ @error
97
+ model UnauthorizedError extends ProblemDetails {
98
+ @statusCode _: 401;
99
+ title: "Unauthorized";
100
+
101
+ @doc("Authentication scheme expected")
102
+ @header("WWW-Authenticate")
103
+ @encodedName("application/json", "www_authenticate")
104
+ wwwAuthenticate?: string;
105
+ }
106
+
107
+ @doc("Forbidden - insufficient permissions (403)")
108
+ @error
109
+ model ForbiddenError extends ProblemDetails {
110
+ @statusCode _: 403;
111
+ title: "Forbidden";
112
+
113
+ @doc("Required permission that is missing")
114
+ @encodedName("application/json", "required_permission")
115
+ requiredPermission?: string;
116
+ }
117
+
118
+ @doc("Conflict - resource state conflict (409)")
119
+ @error
120
+ model ConflictError extends ProblemDetails {
121
+ @statusCode _: 409;
122
+ title: "Conflict";
123
+
124
+ @doc("The conflicting resource ID")
125
+ @encodedName("application/json", "conflicting_resource")
126
+ conflictingResource?: string;
127
+ }
128
+
129
+ @doc("Rate limited - too many requests (429)")
130
+ @error
131
+ model RateLimitError extends ProblemDetails {
132
+ @statusCode _: 429;
133
+ title: "Too Many Requests";
134
+
135
+ @doc("Seconds until the rate limit resets")
136
+ @header("Retry-After")
137
+ @encodedName("application/json", "retry_after")
138
+ retryAfter: int32;
139
+
140
+ @doc("Maximum requests allowed per window")
141
+ @header("X-RateLimit-Limit")
142
+ @encodedName("application/json", "rate_limit")
143
+ rateLimit?: int32;
144
+
145
+ @doc("Remaining requests in current window")
146
+ @header("X-RateLimit-Remaining")
147
+ @encodedName("application/json", "rate_limit_remaining")
148
+ rateLimitRemaining?: int32;
149
+ }
150
+
151
+ @doc("Internal server error (500)")
152
+ @error
153
+ model InternalServerError extends ProblemDetails {
154
+ @statusCode _: 500;
155
+ title: "Internal Server Error";
156
+
157
+ @doc("Error code for support reference")
158
+ @encodedName("application/json", "error_code")
159
+ errorCode?: string;
160
+ }
161
+
162
+ @doc("Service unavailable (503)")
163
+ @error
164
+ model ServiceUnavailableError extends ProblemDetails {
165
+ @statusCode _: 503;
166
+ title: "Service Unavailable";
167
+
168
+ @doc("Expected availability time")
169
+ @header("Retry-After")
170
+ @encodedName("application/json", "retry_after")
171
+ retryAfter?: int32;
172
+
173
+ @doc("Reason for unavailability")
174
+ reason?: "maintenance" | "overloaded" | "dependency_failure";
175
+ }
176
+
177
+ // =============================================================================
178
+ // Error Response Union
179
+ // =============================================================================
180
+
181
+ @doc("Standard error response types")
182
+ union ApiError {
183
+ @doc("Resource not found")
184
+ notFound: NotFoundError,
185
+
186
+ @doc("Validation failed")
187
+ validation: ValidationError,
188
+
189
+ @doc("Authentication required")
190
+ unauthorized: UnauthorizedError,
191
+
192
+ @doc("Permission denied")
193
+ forbidden: ForbiddenError,
194
+
195
+ @doc("Resource conflict")
196
+ conflict: ConflictError,
197
+
198
+ @doc("Rate limit exceeded")
199
+ rateLimit: RateLimitError,
200
+
201
+ @doc("Server error")
202
+ serverError: InternalServerError,
203
+
204
+ @doc("Service unavailable")
205
+ unavailable: ServiceUnavailableError,
206
+ }