@supermodeltools/openapi-spec 0.3.5
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 +2 -0
- package/openapi.yaml +1913 -0
- package/package.json +15 -0
package/openapi.yaml
ADDED
|
@@ -0,0 +1,1913 @@
|
|
|
1
|
+
openapi: 3.0.0
|
|
2
|
+
info:
|
|
3
|
+
title: Supermodel
|
|
4
|
+
description: Code Graphing & Analysis API
|
|
5
|
+
version: 0.3.5
|
|
6
|
+
license:
|
|
7
|
+
name: Supermodel API Terms of Service
|
|
8
|
+
url: https://supermodeltools.com/legal/api-terms
|
|
9
|
+
servers:
|
|
10
|
+
- url: https://api.supermodeltools.com
|
|
11
|
+
description: Production server
|
|
12
|
+
tags:
|
|
13
|
+
- name: Data Plane
|
|
14
|
+
description: Calls the data plane to retrieve Supermodel analysis artifacts derived from repositories.
|
|
15
|
+
paths:
|
|
16
|
+
/v1/graphs/dependency:
|
|
17
|
+
post:
|
|
18
|
+
tags:
|
|
19
|
+
- Data Plane
|
|
20
|
+
summary: Dependency graph
|
|
21
|
+
description: Upload a zipped repository snapshot to generate the dependency graph.
|
|
22
|
+
operationId: generateDependencyGraph
|
|
23
|
+
security:
|
|
24
|
+
- ApiKeyAuth: []
|
|
25
|
+
parameters:
|
|
26
|
+
- $ref: '#/components/parameters/IdempotencyKey'
|
|
27
|
+
requestBody:
|
|
28
|
+
required: true
|
|
29
|
+
content:
|
|
30
|
+
multipart/form-data:
|
|
31
|
+
schema:
|
|
32
|
+
type: object
|
|
33
|
+
required:
|
|
34
|
+
- file
|
|
35
|
+
properties:
|
|
36
|
+
file:
|
|
37
|
+
type: string
|
|
38
|
+
format: binary
|
|
39
|
+
description: Zipped repository archive containing the code to analyze.
|
|
40
|
+
x-codeSamples:
|
|
41
|
+
- lang: cURL
|
|
42
|
+
label: cURL
|
|
43
|
+
source: |
|
|
44
|
+
curl -X POST 'https://api.supermodeltools.com/v1/graphs/dependency' \
|
|
45
|
+
-H 'Idempotency-Key: <idempotency-key>' \
|
|
46
|
+
-H 'X-Api-Key: <api-key>' \
|
|
47
|
+
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
|
|
48
|
+
- lang: javascript
|
|
49
|
+
label: JavaScript (fetch)
|
|
50
|
+
source: |
|
|
51
|
+
import { readFile } from 'node:fs/promises';
|
|
52
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
53
|
+
const apiKey = '<api-key>';
|
|
54
|
+
const idempotencyKey = '<idempotency-key>';
|
|
55
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
56
|
+
|
|
57
|
+
const buffer = await readFile(archivePath);
|
|
58
|
+
const form = new FormData();
|
|
59
|
+
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
|
|
60
|
+
|
|
61
|
+
const res = await fetch(`${baseUrl}/v1/graphs/dependency`, {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: {
|
|
64
|
+
'Idempotency-Key': idempotencyKey,
|
|
65
|
+
'X-Api-Key': apiKey
|
|
66
|
+
},
|
|
67
|
+
body: form
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!res.ok) throw new Error(await res.text());
|
|
71
|
+
console.log(await res.json());
|
|
72
|
+
- lang: typescript
|
|
73
|
+
label: TypeScript (SDK)
|
|
74
|
+
source: |
|
|
75
|
+
import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
|
|
76
|
+
import { readFile } from 'node:fs/promises';
|
|
77
|
+
|
|
78
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
79
|
+
const apiKey = '<api-key>';
|
|
80
|
+
const idempotencyKey = '<idempotency-key>';
|
|
81
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
82
|
+
|
|
83
|
+
const buffer = await readFile(archivePath);
|
|
84
|
+
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
|
|
85
|
+
|
|
86
|
+
const configuration = new Configuration({ basePath: baseUrl });
|
|
87
|
+
|
|
88
|
+
const apiKeyOverride = async ({ init }) => ({
|
|
89
|
+
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const api = new DefaultApi(configuration);
|
|
93
|
+
const result = await api.generateDependencyGraph(
|
|
94
|
+
{ idempotencyKey, file: archiveBlob },
|
|
95
|
+
apiKeyOverride
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
console.log(result);
|
|
99
|
+
- lang: java
|
|
100
|
+
label: Java (generated client)
|
|
101
|
+
source: |
|
|
102
|
+
import org.openapitools.client.ApiClient;
|
|
103
|
+
import org.openapitools.client.api.DefaultApi;
|
|
104
|
+
|
|
105
|
+
import java.io.File;
|
|
106
|
+
|
|
107
|
+
public class Example {
|
|
108
|
+
public static void main(String[] args) throws Exception {
|
|
109
|
+
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
|
|
110
|
+
String apiKey = "<api-key>";
|
|
111
|
+
String idempotencyKey = "<idempotency-key>";
|
|
112
|
+
File archive = new File("/path/to/your/repo-snapshot.zip");
|
|
113
|
+
|
|
114
|
+
ApiClient client = new ApiClient();
|
|
115
|
+
client.updateBaseUri(baseUrl);
|
|
116
|
+
client.setRequestInterceptor(rb -> {
|
|
117
|
+
rb.header("X-Api-Key", apiKey);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
DefaultApi api = new DefaultApi(client);
|
|
121
|
+
api.generateDependencyGraph(idempotencyKey, archive);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
- lang: python
|
|
125
|
+
label: Python (generated client)
|
|
126
|
+
source: |
|
|
127
|
+
import os
|
|
128
|
+
from supermodel_public_api import ApiClient, Configuration
|
|
129
|
+
from supermodel_public_api.api.default_api import DefaultApi
|
|
130
|
+
|
|
131
|
+
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
|
|
132
|
+
api_key = "<api-key>"
|
|
133
|
+
idempotency_key = "<idempotency-key>"
|
|
134
|
+
|
|
135
|
+
configuration = Configuration(host=base_url)
|
|
136
|
+
configuration.api_key["ApiKeyAuth"] = api_key
|
|
137
|
+
|
|
138
|
+
api_client = ApiClient(configuration)
|
|
139
|
+
api = DefaultApi(api_client)
|
|
140
|
+
|
|
141
|
+
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
|
|
142
|
+
payload = f.read()
|
|
143
|
+
|
|
144
|
+
result = api.generate_dependency_graph(idempotency_key, file=payload)
|
|
145
|
+
print(result)
|
|
146
|
+
- lang: rust
|
|
147
|
+
label: Rust (reqwest)
|
|
148
|
+
source: |
|
|
149
|
+
use bytes::Bytes;
|
|
150
|
+
use reqwest::multipart::{Form, Part};
|
|
151
|
+
|
|
152
|
+
#[tokio::main]
|
|
153
|
+
async fn main() -> anyhow::Result<()> {
|
|
154
|
+
let base_url = std::env::var("API_BASE_URL")
|
|
155
|
+
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
|
|
156
|
+
let api_key = "<api-key>";
|
|
157
|
+
let idempotency_key = "<idempotency-key>";
|
|
158
|
+
|
|
159
|
+
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
|
|
160
|
+
let url = format!("{}/v1/graphs/dependency", base_url.trim_end_matches('/'));
|
|
161
|
+
|
|
162
|
+
let file_part = Part::bytes(archive_bytes.to_vec())
|
|
163
|
+
.file_name("repo.zip")
|
|
164
|
+
.mime_str("application/zip")?;
|
|
165
|
+
let form = Form::new().part("file", file_part);
|
|
166
|
+
|
|
167
|
+
let response = reqwest::Client::new()
|
|
168
|
+
.post(url)
|
|
169
|
+
.header("Idempotency-Key", idempotency_key)
|
|
170
|
+
.header("X-Api-Key", api_key)
|
|
171
|
+
.multipart(form)
|
|
172
|
+
.send()
|
|
173
|
+
.await?;
|
|
174
|
+
let status = response.status();
|
|
175
|
+
let body = response.bytes().await?;
|
|
176
|
+
|
|
177
|
+
if status.is_success() {
|
|
178
|
+
println!("{}", String::from_utf8_lossy(&body));
|
|
179
|
+
} else {
|
|
180
|
+
anyhow::bail!(
|
|
181
|
+
"Request failed ({}): {}",
|
|
182
|
+
status.as_u16(),
|
|
183
|
+
String::from_utf8_lossy(&body)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Ok(())
|
|
188
|
+
}
|
|
189
|
+
responses:
|
|
190
|
+
'200':
|
|
191
|
+
description: Dependency graph
|
|
192
|
+
headers:
|
|
193
|
+
X-Request-Id:
|
|
194
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
195
|
+
X-API-Version:
|
|
196
|
+
$ref: '#/components/headers/X-API-Version'
|
|
197
|
+
RateLimit-Limit:
|
|
198
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
199
|
+
RateLimit-Remaining:
|
|
200
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
201
|
+
RateLimit-Reset:
|
|
202
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
203
|
+
X-Usage-Units:
|
|
204
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
205
|
+
content:
|
|
206
|
+
application/json:
|
|
207
|
+
schema:
|
|
208
|
+
$ref: '#/components/schemas/CodeGraphEnvelope'
|
|
209
|
+
example:
|
|
210
|
+
generatedAt: '2025-02-05 15:42:10.000000000 Z'
|
|
211
|
+
message: Graph generated successfully
|
|
212
|
+
stats:
|
|
213
|
+
filesProcessed: 2
|
|
214
|
+
classes: 0
|
|
215
|
+
functions: 0
|
|
216
|
+
types: 0
|
|
217
|
+
processingTimeMs: 15
|
|
218
|
+
graph:
|
|
219
|
+
nodes:
|
|
220
|
+
- id: src/main.js
|
|
221
|
+
labels:
|
|
222
|
+
- File
|
|
223
|
+
properties:
|
|
224
|
+
path: src/main.js
|
|
225
|
+
name: main.js
|
|
226
|
+
- id: src/math.js
|
|
227
|
+
labels:
|
|
228
|
+
- File
|
|
229
|
+
properties:
|
|
230
|
+
path: src/math.js
|
|
231
|
+
name: math.js
|
|
232
|
+
relationships:
|
|
233
|
+
- id: src/main.js_imports_src/math.js
|
|
234
|
+
type: imports
|
|
235
|
+
startNode: src/main.js
|
|
236
|
+
endNode: src/math.js
|
|
237
|
+
properties: {}
|
|
238
|
+
'400':
|
|
239
|
+
$ref: '#/components/responses/BadRequest'
|
|
240
|
+
'401':
|
|
241
|
+
$ref: '#/components/responses/Unauthorized'
|
|
242
|
+
'403':
|
|
243
|
+
$ref: '#/components/responses/Forbidden'
|
|
244
|
+
'404':
|
|
245
|
+
$ref: '#/components/responses/NotFound'
|
|
246
|
+
'429':
|
|
247
|
+
$ref: '#/components/responses/TooManyRequests'
|
|
248
|
+
'500':
|
|
249
|
+
$ref: '#/components/responses/InternalError'
|
|
250
|
+
'502':
|
|
251
|
+
description: Bad Gateway
|
|
252
|
+
content:
|
|
253
|
+
application/json:
|
|
254
|
+
schema:
|
|
255
|
+
$ref: '#/components/schemas/Error'
|
|
256
|
+
/v1/graphs/call:
|
|
257
|
+
post:
|
|
258
|
+
tags:
|
|
259
|
+
- Data Plane
|
|
260
|
+
summary: Call graph
|
|
261
|
+
description: Upload a zipped repository snapshot to generate the function-level call graph.
|
|
262
|
+
operationId: generateCallGraph
|
|
263
|
+
security:
|
|
264
|
+
- ApiKeyAuth: []
|
|
265
|
+
parameters:
|
|
266
|
+
- $ref: '#/components/parameters/IdempotencyKey'
|
|
267
|
+
requestBody:
|
|
268
|
+
required: true
|
|
269
|
+
content:
|
|
270
|
+
multipart/form-data:
|
|
271
|
+
schema:
|
|
272
|
+
type: object
|
|
273
|
+
required:
|
|
274
|
+
- file
|
|
275
|
+
properties:
|
|
276
|
+
file:
|
|
277
|
+
type: string
|
|
278
|
+
format: binary
|
|
279
|
+
description: Zipped repository archive containing the code to analyze.
|
|
280
|
+
x-codeSamples:
|
|
281
|
+
- lang: cURL
|
|
282
|
+
label: cURL
|
|
283
|
+
source: |
|
|
284
|
+
curl -X POST 'https://api.supermodeltools.com/v1/graphs/call' \
|
|
285
|
+
-H 'Idempotency-Key: <idempotency-key>' \
|
|
286
|
+
-H 'X-Api-Key: <api-key>' \
|
|
287
|
+
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
|
|
288
|
+
- lang: javascript
|
|
289
|
+
label: JavaScript (fetch)
|
|
290
|
+
source: |
|
|
291
|
+
import { readFile } from 'node:fs/promises';
|
|
292
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
293
|
+
const apiKey = '<api-key>';
|
|
294
|
+
const idempotencyKey = '<idempotency-key>';
|
|
295
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
296
|
+
|
|
297
|
+
const buffer = await readFile(archivePath);
|
|
298
|
+
const form = new FormData();
|
|
299
|
+
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
|
|
300
|
+
|
|
301
|
+
const res = await fetch(`${baseUrl}/v1/graphs/call`, {
|
|
302
|
+
method: 'POST',
|
|
303
|
+
headers: {
|
|
304
|
+
'Idempotency-Key': idempotencyKey,
|
|
305
|
+
'X-Api-Key': apiKey
|
|
306
|
+
},
|
|
307
|
+
body: form
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
if (!res.ok) throw new Error(await res.text());
|
|
311
|
+
console.log(await res.json());
|
|
312
|
+
- lang: typescript
|
|
313
|
+
label: TypeScript (SDK)
|
|
314
|
+
source: |
|
|
315
|
+
import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
|
|
316
|
+
import { readFile } from 'node:fs/promises';
|
|
317
|
+
|
|
318
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
319
|
+
const apiKey = '<api-key>';
|
|
320
|
+
const idempotencyKey = '<idempotency-key>';
|
|
321
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
322
|
+
|
|
323
|
+
const buffer = await readFile(archivePath);
|
|
324
|
+
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
|
|
325
|
+
|
|
326
|
+
const configuration = new Configuration({ basePath: baseUrl });
|
|
327
|
+
|
|
328
|
+
const apiKeyOverride = async ({ init }) => ({
|
|
329
|
+
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const api = new DefaultApi(configuration);
|
|
333
|
+
const result = await api.generateCallGraph(
|
|
334
|
+
{ idempotencyKey, file: archiveBlob },
|
|
335
|
+
apiKeyOverride
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
console.log(result);
|
|
339
|
+
- lang: java
|
|
340
|
+
label: Java (generated client)
|
|
341
|
+
source: |
|
|
342
|
+
import org.openapitools.client.ApiClient;
|
|
343
|
+
import org.openapitools.client.api.DefaultApi;
|
|
344
|
+
|
|
345
|
+
import java.io.File;
|
|
346
|
+
|
|
347
|
+
public class Example {
|
|
348
|
+
public static void main(String[] args) throws Exception {
|
|
349
|
+
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
|
|
350
|
+
String apiKey = "<api-key>";
|
|
351
|
+
String idempotencyKey = "<idempotency-key>";
|
|
352
|
+
File archive = new File("/path/to/your/repo-snapshot.zip");
|
|
353
|
+
|
|
354
|
+
ApiClient client = new ApiClient();
|
|
355
|
+
client.updateBaseUri(baseUrl);
|
|
356
|
+
client.setRequestInterceptor(rb -> {
|
|
357
|
+
rb.header("X-Api-Key", apiKey);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
DefaultApi api = new DefaultApi(client);
|
|
361
|
+
api.generateCallGraph(idempotencyKey, archive);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
- lang: python
|
|
365
|
+
label: Python (generated client)
|
|
366
|
+
source: |
|
|
367
|
+
import os
|
|
368
|
+
from supermodel_public_api import ApiClient, Configuration
|
|
369
|
+
from supermodel_public_api.api.default_api import DefaultApi
|
|
370
|
+
|
|
371
|
+
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
|
|
372
|
+
api_key = "<api-key>"
|
|
373
|
+
idempotency_key = "<idempotency-key>"
|
|
374
|
+
|
|
375
|
+
configuration = Configuration(host=base_url)
|
|
376
|
+
configuration.api_key["ApiKeyAuth"] = api_key
|
|
377
|
+
|
|
378
|
+
api_client = ApiClient(configuration)
|
|
379
|
+
api = DefaultApi(api_client)
|
|
380
|
+
|
|
381
|
+
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
|
|
382
|
+
payload = f.read()
|
|
383
|
+
|
|
384
|
+
result = api.generate_call_graph(idempotency_key, file=payload)
|
|
385
|
+
print(result)
|
|
386
|
+
- lang: rust
|
|
387
|
+
label: Rust (reqwest)
|
|
388
|
+
source: |
|
|
389
|
+
use bytes::Bytes;
|
|
390
|
+
use reqwest::multipart::{Form, Part};
|
|
391
|
+
|
|
392
|
+
#[tokio::main]
|
|
393
|
+
async fn main() -> anyhow::Result<()> {
|
|
394
|
+
let base_url = std::env::var("API_BASE_URL")
|
|
395
|
+
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
|
|
396
|
+
let api_key = "<api-key>";
|
|
397
|
+
let idempotency_key = "<idempotency-key>";
|
|
398
|
+
|
|
399
|
+
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
|
|
400
|
+
let url = format!("{}/v1/graphs/call", base_url.trim_end_matches('/'));
|
|
401
|
+
|
|
402
|
+
let file_part = Part::bytes(archive_bytes.to_vec())
|
|
403
|
+
.file_name("repo.zip")
|
|
404
|
+
.mime_str("application/zip")?;
|
|
405
|
+
let form = Form::new().part("file", file_part);
|
|
406
|
+
|
|
407
|
+
let response = reqwest::Client::new()
|
|
408
|
+
.post(url)
|
|
409
|
+
.header("Idempotency-Key", idempotency_key)
|
|
410
|
+
.header("X-Api-Key", api_key)
|
|
411
|
+
.multipart(form)
|
|
412
|
+
.send()
|
|
413
|
+
.await?;
|
|
414
|
+
let status = response.status();
|
|
415
|
+
let body = response.bytes().await?;
|
|
416
|
+
|
|
417
|
+
if status.is_success() {
|
|
418
|
+
println!("{}", String::from_utf8_lossy(&body));
|
|
419
|
+
} else {
|
|
420
|
+
anyhow::bail!(
|
|
421
|
+
"Request failed ({}): {}",
|
|
422
|
+
status.as_u16(),
|
|
423
|
+
String::from_utf8_lossy(&body)
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
Ok(())
|
|
428
|
+
}
|
|
429
|
+
responses:
|
|
430
|
+
'200':
|
|
431
|
+
description: Call graph
|
|
432
|
+
headers:
|
|
433
|
+
X-Request-Id:
|
|
434
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
435
|
+
X-API-Version:
|
|
436
|
+
$ref: '#/components/headers/X-API-Version'
|
|
437
|
+
RateLimit-Limit:
|
|
438
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
439
|
+
RateLimit-Remaining:
|
|
440
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
441
|
+
RateLimit-Reset:
|
|
442
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
443
|
+
X-Usage-Units:
|
|
444
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
445
|
+
content:
|
|
446
|
+
application/json:
|
|
447
|
+
schema:
|
|
448
|
+
$ref: '#/components/schemas/CodeGraphEnvelope'
|
|
449
|
+
example:
|
|
450
|
+
generatedAt: '2025-02-05 15:42:10.000000000 Z'
|
|
451
|
+
message: Call graph generated successfully
|
|
452
|
+
stats:
|
|
453
|
+
filesProcessed: 2
|
|
454
|
+
classes: 0
|
|
455
|
+
functions: 2
|
|
456
|
+
types: 0
|
|
457
|
+
processingTimeMs: 8
|
|
458
|
+
graph:
|
|
459
|
+
nodes:
|
|
460
|
+
- id: fn:index.ts:init
|
|
461
|
+
labels:
|
|
462
|
+
- Function
|
|
463
|
+
properties:
|
|
464
|
+
file: src/index.ts
|
|
465
|
+
- id: fn:service.ts:handle
|
|
466
|
+
labels:
|
|
467
|
+
- Function
|
|
468
|
+
properties:
|
|
469
|
+
file: src/service.ts
|
|
470
|
+
relationships:
|
|
471
|
+
- id: fn:index.ts:init_calls_fn:service.ts:handle
|
|
472
|
+
type: calls
|
|
473
|
+
startNode: fn:index.ts:init
|
|
474
|
+
endNode: fn:service.ts:handle
|
|
475
|
+
properties:
|
|
476
|
+
count: 4
|
|
477
|
+
'400':
|
|
478
|
+
$ref: '#/components/responses/BadRequest'
|
|
479
|
+
'401':
|
|
480
|
+
$ref: '#/components/responses/Unauthorized'
|
|
481
|
+
'403':
|
|
482
|
+
$ref: '#/components/responses/Forbidden'
|
|
483
|
+
'404':
|
|
484
|
+
$ref: '#/components/responses/NotFound'
|
|
485
|
+
'429':
|
|
486
|
+
$ref: '#/components/responses/TooManyRequests'
|
|
487
|
+
'500':
|
|
488
|
+
$ref: '#/components/responses/InternalError'
|
|
489
|
+
'502':
|
|
490
|
+
description: Bad Gateway
|
|
491
|
+
content:
|
|
492
|
+
application/json:
|
|
493
|
+
schema:
|
|
494
|
+
$ref: '#/components/schemas/Error'
|
|
495
|
+
/v1/graphs/domain:
|
|
496
|
+
post:
|
|
497
|
+
tags:
|
|
498
|
+
- Data Plane
|
|
499
|
+
summary: Domain graph
|
|
500
|
+
description: Upload a zipped repository snapshot to generate the domain model graph.
|
|
501
|
+
operationId: generateDomainGraph
|
|
502
|
+
security:
|
|
503
|
+
- ApiKeyAuth: []
|
|
504
|
+
parameters:
|
|
505
|
+
- $ref: '#/components/parameters/IdempotencyKey'
|
|
506
|
+
requestBody:
|
|
507
|
+
required: true
|
|
508
|
+
content:
|
|
509
|
+
multipart/form-data:
|
|
510
|
+
schema:
|
|
511
|
+
type: object
|
|
512
|
+
required:
|
|
513
|
+
- file
|
|
514
|
+
properties:
|
|
515
|
+
file:
|
|
516
|
+
type: string
|
|
517
|
+
format: binary
|
|
518
|
+
description: Zipped repository archive containing the code to analyze.
|
|
519
|
+
x-codeSamples:
|
|
520
|
+
- lang: cURL
|
|
521
|
+
label: cURL
|
|
522
|
+
source: |
|
|
523
|
+
curl -X POST 'https://api.supermodeltools.com/v1/graphs/domain' \
|
|
524
|
+
-H 'Idempotency-Key: <idempotency-key>' \
|
|
525
|
+
-H 'X-Api-Key: <api-key>' \
|
|
526
|
+
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
|
|
527
|
+
- lang: javascript
|
|
528
|
+
label: JavaScript (fetch)
|
|
529
|
+
source: |
|
|
530
|
+
import { readFile } from 'node:fs/promises';
|
|
531
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
532
|
+
const apiKey = '<api-key>';
|
|
533
|
+
const idempotencyKey = '<idempotency-key>';
|
|
534
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
535
|
+
|
|
536
|
+
const buffer = await readFile(archivePath);
|
|
537
|
+
const form = new FormData();
|
|
538
|
+
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
|
|
539
|
+
|
|
540
|
+
const res = await fetch(`${baseUrl}/v1/graphs/domain`, {
|
|
541
|
+
method: 'POST',
|
|
542
|
+
headers: {
|
|
543
|
+
'Idempotency-Key': idempotencyKey,
|
|
544
|
+
'X-Api-Key': apiKey
|
|
545
|
+
},
|
|
546
|
+
body: form
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
if (!res.ok) throw new Error(await res.text());
|
|
550
|
+
console.log(await res.json());
|
|
551
|
+
- lang: typescript
|
|
552
|
+
label: TypeScript (SDK)
|
|
553
|
+
source: |
|
|
554
|
+
import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
|
|
555
|
+
import { readFile } from 'node:fs/promises';
|
|
556
|
+
|
|
557
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
558
|
+
const apiKey = '<api-key>';
|
|
559
|
+
const idempotencyKey = '<idempotency-key>';
|
|
560
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
561
|
+
|
|
562
|
+
const buffer = await readFile(archivePath);
|
|
563
|
+
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
|
|
564
|
+
|
|
565
|
+
const configuration = new Configuration({ basePath: baseUrl });
|
|
566
|
+
|
|
567
|
+
const apiKeyOverride = async ({ init }) => ({
|
|
568
|
+
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
const api = new DefaultApi(configuration);
|
|
572
|
+
const result = await api.generateDomainGraph(
|
|
573
|
+
{ idempotencyKey, file: archiveBlob },
|
|
574
|
+
apiKeyOverride
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
console.log(result);
|
|
578
|
+
- lang: java
|
|
579
|
+
label: Java (generated client)
|
|
580
|
+
source: |
|
|
581
|
+
import org.openapitools.client.ApiClient;
|
|
582
|
+
import org.openapitools.client.api.DefaultApi;
|
|
583
|
+
|
|
584
|
+
import java.io.File;
|
|
585
|
+
|
|
586
|
+
public class Example {
|
|
587
|
+
public static void main(String[] args) throws Exception {
|
|
588
|
+
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
|
|
589
|
+
String apiKey = "<api-key>";
|
|
590
|
+
String idempotencyKey = "<idempotency-key>";
|
|
591
|
+
File archive = new File("/path/to/your/repo-snapshot.zip");
|
|
592
|
+
|
|
593
|
+
ApiClient client = new ApiClient();
|
|
594
|
+
client.updateBaseUri(baseUrl);
|
|
595
|
+
client.setRequestInterceptor(rb -> {
|
|
596
|
+
rb.header("X-Api-Key", apiKey);
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
DefaultApi api = new DefaultApi(client);
|
|
600
|
+
api.generateDomainGraph(idempotencyKey, archive);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
- lang: python
|
|
604
|
+
label: Python (generated client)
|
|
605
|
+
source: |
|
|
606
|
+
import os
|
|
607
|
+
from supermodel_public_api import ApiClient, Configuration
|
|
608
|
+
from supermodel_public_api.api.default_api import DefaultApi
|
|
609
|
+
|
|
610
|
+
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
|
|
611
|
+
api_key = "<api-key>"
|
|
612
|
+
idempotency_key = "<idempotency-key>"
|
|
613
|
+
|
|
614
|
+
configuration = Configuration(host=base_url)
|
|
615
|
+
configuration.api_key["ApiKeyAuth"] = api_key
|
|
616
|
+
|
|
617
|
+
api_client = ApiClient(configuration)
|
|
618
|
+
api = DefaultApi(api_client)
|
|
619
|
+
|
|
620
|
+
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
|
|
621
|
+
payload = f.read()
|
|
622
|
+
|
|
623
|
+
result = api.generate_domain_graph(idempotency_key, file=payload)
|
|
624
|
+
print(result)
|
|
625
|
+
- lang: rust
|
|
626
|
+
label: Rust (reqwest)
|
|
627
|
+
source: |
|
|
628
|
+
use bytes::Bytes;
|
|
629
|
+
use reqwest::multipart::{Form, Part};
|
|
630
|
+
|
|
631
|
+
#[tokio::main]
|
|
632
|
+
async fn main() -> anyhow::Result<()> {
|
|
633
|
+
let base_url = std::env::var("API_BASE_URL")
|
|
634
|
+
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
|
|
635
|
+
let api_key = "<api-key>";
|
|
636
|
+
let idempotency_key = "<idempotency-key>";
|
|
637
|
+
|
|
638
|
+
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
|
|
639
|
+
let url = format!("{}/v1/graphs/domain", base_url.trim_end_matches('/'));
|
|
640
|
+
|
|
641
|
+
let file_part = Part::bytes(archive_bytes.to_vec())
|
|
642
|
+
.file_name("repo.zip")
|
|
643
|
+
.mime_str("application/zip")?;
|
|
644
|
+
let form = Form::new().part("file", file_part);
|
|
645
|
+
|
|
646
|
+
let response = reqwest::Client::new()
|
|
647
|
+
.post(url)
|
|
648
|
+
.header("Idempotency-Key", idempotency_key)
|
|
649
|
+
.header("X-Api-Key", api_key)
|
|
650
|
+
.multipart(form)
|
|
651
|
+
.send()
|
|
652
|
+
.await?;
|
|
653
|
+
let status = response.status();
|
|
654
|
+
let body = response.bytes().await?;
|
|
655
|
+
|
|
656
|
+
if status.is_success() {
|
|
657
|
+
println!("{}", String::from_utf8_lossy(&body));
|
|
658
|
+
} else {
|
|
659
|
+
anyhow::bail!(
|
|
660
|
+
"Request failed ({}): {}",
|
|
661
|
+
status.as_u16(),
|
|
662
|
+
String::from_utf8_lossy(&body)
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
Ok(())
|
|
667
|
+
}
|
|
668
|
+
responses:
|
|
669
|
+
'200':
|
|
670
|
+
description: Domain graph
|
|
671
|
+
headers:
|
|
672
|
+
X-Request-Id:
|
|
673
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
674
|
+
X-API-Version:
|
|
675
|
+
$ref: '#/components/headers/X-API-Version'
|
|
676
|
+
RateLimit-Limit:
|
|
677
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
678
|
+
RateLimit-Remaining:
|
|
679
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
680
|
+
RateLimit-Reset:
|
|
681
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
682
|
+
X-Usage-Units:
|
|
683
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
684
|
+
content:
|
|
685
|
+
application/json:
|
|
686
|
+
schema:
|
|
687
|
+
$ref: '#/components/schemas/DomainClassificationResponse'
|
|
688
|
+
example:
|
|
689
|
+
runId: smart-sampling-a1b2c3d4
|
|
690
|
+
domains:
|
|
691
|
+
- name: BillingAccount
|
|
692
|
+
descriptionSummary: Handles billing and account management
|
|
693
|
+
keyFiles:
|
|
694
|
+
- src/domain/billing.ts
|
|
695
|
+
- src/services/billing.service.ts
|
|
696
|
+
responsibilities:
|
|
697
|
+
- Account creation
|
|
698
|
+
- Payment processing
|
|
699
|
+
subdomains:
|
|
700
|
+
- name: PaymentProcessing
|
|
701
|
+
descriptionSummary: Processes payment transactions
|
|
702
|
+
- name: UsageSummary
|
|
703
|
+
descriptionSummary: Tracks and summarizes usage metrics
|
|
704
|
+
keyFiles:
|
|
705
|
+
- src/domain/usage.ts
|
|
706
|
+
responsibilities:
|
|
707
|
+
- Usage tracking
|
|
708
|
+
- Metrics aggregation
|
|
709
|
+
subdomains: []
|
|
710
|
+
relationships:
|
|
711
|
+
- from: BillingAccount
|
|
712
|
+
to: UsageSummary
|
|
713
|
+
type: aggregates
|
|
714
|
+
strength: 0.8
|
|
715
|
+
reason: BillingAccount aggregates usage data for billing purposes
|
|
716
|
+
fileAssignments:
|
|
717
|
+
- filePath: src/domain/billing.ts
|
|
718
|
+
domainName: BillingAccount
|
|
719
|
+
- filePath: src/domain/usage.ts
|
|
720
|
+
domainName: UsageSummary
|
|
721
|
+
functionAssignments:
|
|
722
|
+
- functionId: func-123
|
|
723
|
+
subdomainName: PaymentProcessing
|
|
724
|
+
parentDomain: BillingAccount
|
|
725
|
+
unassignedFunctions:
|
|
726
|
+
- functionId: func-456
|
|
727
|
+
reason: Utility function with unclear domain association
|
|
728
|
+
classAssignments:
|
|
729
|
+
- classId: class-789
|
|
730
|
+
domainName: BillingAccount
|
|
731
|
+
functionDescriptions:
|
|
732
|
+
- functionId: func-123
|
|
733
|
+
descriptionSummary: Processes incoming payment transactions
|
|
734
|
+
domainName: BillingAccount
|
|
735
|
+
- functionId: func-456
|
|
736
|
+
descriptionSummary: Aggregates usage metrics for billing period
|
|
737
|
+
stats:
|
|
738
|
+
domainCount: 2
|
|
739
|
+
relationshipCount: 1
|
|
740
|
+
fileAssignments: 2
|
|
741
|
+
functionAssignments: 1
|
|
742
|
+
unassignedFunctions: 1
|
|
743
|
+
classAssignments: 1
|
|
744
|
+
'400':
|
|
745
|
+
$ref: '#/components/responses/BadRequest'
|
|
746
|
+
'401':
|
|
747
|
+
$ref: '#/components/responses/Unauthorized'
|
|
748
|
+
'403':
|
|
749
|
+
$ref: '#/components/responses/Forbidden'
|
|
750
|
+
'404':
|
|
751
|
+
$ref: '#/components/responses/NotFound'
|
|
752
|
+
'429':
|
|
753
|
+
$ref: '#/components/responses/TooManyRequests'
|
|
754
|
+
'500':
|
|
755
|
+
$ref: '#/components/responses/InternalError'
|
|
756
|
+
'502':
|
|
757
|
+
description: Bad Gateway
|
|
758
|
+
content:
|
|
759
|
+
application/json:
|
|
760
|
+
schema:
|
|
761
|
+
$ref: '#/components/schemas/Error'
|
|
762
|
+
/v1/graphs/parse:
|
|
763
|
+
post:
|
|
764
|
+
tags:
|
|
765
|
+
- Data Plane
|
|
766
|
+
summary: Parse graph
|
|
767
|
+
description: Upload a zipped repository snapshot to generate parse tree relationships.
|
|
768
|
+
operationId: generateParseGraph
|
|
769
|
+
security:
|
|
770
|
+
- ApiKeyAuth: []
|
|
771
|
+
parameters:
|
|
772
|
+
- $ref: '#/components/parameters/IdempotencyKey'
|
|
773
|
+
requestBody:
|
|
774
|
+
required: true
|
|
775
|
+
content:
|
|
776
|
+
multipart/form-data:
|
|
777
|
+
schema:
|
|
778
|
+
type: object
|
|
779
|
+
required:
|
|
780
|
+
- file
|
|
781
|
+
properties:
|
|
782
|
+
file:
|
|
783
|
+
type: string
|
|
784
|
+
format: binary
|
|
785
|
+
description: Zipped repository archive containing the code to analyze.
|
|
786
|
+
x-codeSamples:
|
|
787
|
+
- lang: cURL
|
|
788
|
+
label: cURL
|
|
789
|
+
source: |
|
|
790
|
+
curl -X POST 'https://api.supermodeltools.com/v1/graphs/parse' \
|
|
791
|
+
-H 'Idempotency-Key: <idempotency-key>' \
|
|
792
|
+
-H 'X-Api-Key: <api-key>' \
|
|
793
|
+
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
|
|
794
|
+
- lang: javascript
|
|
795
|
+
label: JavaScript (fetch)
|
|
796
|
+
source: |
|
|
797
|
+
import { readFile } from 'node:fs/promises';
|
|
798
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
799
|
+
const apiKey = '<api-key>';
|
|
800
|
+
const idempotencyKey = '<idempotency-key>';
|
|
801
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
802
|
+
|
|
803
|
+
const buffer = await readFile(archivePath);
|
|
804
|
+
const form = new FormData();
|
|
805
|
+
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
|
|
806
|
+
|
|
807
|
+
const res = await fetch(`${baseUrl}/v1/graphs/parse`, {
|
|
808
|
+
method: 'POST',
|
|
809
|
+
headers: {
|
|
810
|
+
'Idempotency-Key': idempotencyKey,
|
|
811
|
+
'X-Api-Key': apiKey
|
|
812
|
+
},
|
|
813
|
+
body: form
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
if (!res.ok) throw new Error(await res.text());
|
|
817
|
+
console.log(await res.json());
|
|
818
|
+
- lang: typescript
|
|
819
|
+
label: TypeScript (SDK)
|
|
820
|
+
source: |
|
|
821
|
+
import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
|
|
822
|
+
import { readFile } from 'node:fs/promises';
|
|
823
|
+
|
|
824
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
825
|
+
const apiKey = '<api-key>';
|
|
826
|
+
const idempotencyKey = '<idempotency-key>';
|
|
827
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
828
|
+
|
|
829
|
+
const buffer = await readFile(archivePath);
|
|
830
|
+
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
|
|
831
|
+
|
|
832
|
+
const configuration = new Configuration({ basePath: baseUrl });
|
|
833
|
+
|
|
834
|
+
const apiKeyOverride = async ({ init }) => ({
|
|
835
|
+
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
const api = new DefaultApi(configuration);
|
|
839
|
+
const result = await api.generateParseGraph(
|
|
840
|
+
{ idempotencyKey, file: archiveBlob },
|
|
841
|
+
apiKeyOverride
|
|
842
|
+
);
|
|
843
|
+
|
|
844
|
+
console.log(result);
|
|
845
|
+
- lang: java
|
|
846
|
+
label: Java (generated client)
|
|
847
|
+
source: |
|
|
848
|
+
import org.openapitools.client.ApiClient;
|
|
849
|
+
import org.openapitools.client.api.DefaultApi;
|
|
850
|
+
|
|
851
|
+
import java.io.File;
|
|
852
|
+
|
|
853
|
+
public class Example {
|
|
854
|
+
public static void main(String[] args) throws Exception {
|
|
855
|
+
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
|
|
856
|
+
String apiKey = "<api-key>";
|
|
857
|
+
String idempotencyKey = "<idempotency-key>";
|
|
858
|
+
File archive = new File("/path/to/your/repo-snapshot.zip");
|
|
859
|
+
|
|
860
|
+
ApiClient client = new ApiClient();
|
|
861
|
+
client.updateBaseUri(baseUrl);
|
|
862
|
+
client.setRequestInterceptor(rb -> {
|
|
863
|
+
rb.header("X-Api-Key", apiKey);
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
DefaultApi api = new DefaultApi(client);
|
|
867
|
+
api.generateParseGraph(idempotencyKey, archive);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
- lang: python
|
|
871
|
+
label: Python (generated client)
|
|
872
|
+
source: |
|
|
873
|
+
import os
|
|
874
|
+
from supermodel_public_api import ApiClient, Configuration
|
|
875
|
+
from supermodel_public_api.api.default_api import DefaultApi
|
|
876
|
+
|
|
877
|
+
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
|
|
878
|
+
api_key = "<api-key>"
|
|
879
|
+
idempotency_key = "<idempotency-key>"
|
|
880
|
+
|
|
881
|
+
configuration = Configuration(host=base_url)
|
|
882
|
+
configuration.api_key["ApiKeyAuth"] = api_key
|
|
883
|
+
|
|
884
|
+
api_client = ApiClient(configuration)
|
|
885
|
+
api = DefaultApi(api_client)
|
|
886
|
+
|
|
887
|
+
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
|
|
888
|
+
payload = f.read()
|
|
889
|
+
|
|
890
|
+
result = api.generate_parse_graph(idempotency_key, file=payload)
|
|
891
|
+
print(result)
|
|
892
|
+
- lang: rust
|
|
893
|
+
label: Rust (reqwest)
|
|
894
|
+
source: |
|
|
895
|
+
use bytes::Bytes;
|
|
896
|
+
use reqwest::multipart::{Form, Part};
|
|
897
|
+
|
|
898
|
+
#[tokio::main]
|
|
899
|
+
async fn main() -> anyhow::Result<()> {
|
|
900
|
+
let base_url = std::env::var("API_BASE_URL")
|
|
901
|
+
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
|
|
902
|
+
let api_key = "<api-key>";
|
|
903
|
+
let idempotency_key = "<idempotency-key>";
|
|
904
|
+
|
|
905
|
+
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
|
|
906
|
+
let url = format!("{}/v1/graphs/parse", base_url.trim_end_matches('/'));
|
|
907
|
+
|
|
908
|
+
let file_part = Part::bytes(archive_bytes.to_vec())
|
|
909
|
+
.file_name("repo.zip")
|
|
910
|
+
.mime_str("application/zip")?;
|
|
911
|
+
let form = Form::new().part("file", file_part);
|
|
912
|
+
|
|
913
|
+
let response = reqwest::Client::new()
|
|
914
|
+
.post(url)
|
|
915
|
+
.header("Idempotency-Key", idempotency_key)
|
|
916
|
+
.header("X-Api-Key", api_key)
|
|
917
|
+
.multipart(form)
|
|
918
|
+
.send()
|
|
919
|
+
.await?;
|
|
920
|
+
let status = response.status();
|
|
921
|
+
let body = response.bytes().await?;
|
|
922
|
+
|
|
923
|
+
if status.is_success() {
|
|
924
|
+
println!("{}", String::from_utf8_lossy(&body));
|
|
925
|
+
} else {
|
|
926
|
+
anyhow::bail!(
|
|
927
|
+
"Request failed ({}): {}",
|
|
928
|
+
status.as_u16(),
|
|
929
|
+
String::from_utf8_lossy(&body)
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
Ok(())
|
|
934
|
+
}
|
|
935
|
+
responses:
|
|
936
|
+
'200':
|
|
937
|
+
description: Parse graph
|
|
938
|
+
headers:
|
|
939
|
+
X-Request-Id:
|
|
940
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
941
|
+
X-API-Version:
|
|
942
|
+
$ref: '#/components/headers/X-API-Version'
|
|
943
|
+
RateLimit-Limit:
|
|
944
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
945
|
+
RateLimit-Remaining:
|
|
946
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
947
|
+
RateLimit-Reset:
|
|
948
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
949
|
+
X-Usage-Units:
|
|
950
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
951
|
+
content:
|
|
952
|
+
application/json:
|
|
953
|
+
schema:
|
|
954
|
+
$ref: '#/components/schemas/CodeGraphEnvelope'
|
|
955
|
+
example:
|
|
956
|
+
generatedAt: '2025-02-05 15:42:10.000000000 Z'
|
|
957
|
+
message: Parse graph generated successfully
|
|
958
|
+
stats:
|
|
959
|
+
filesProcessed: 1
|
|
960
|
+
classes: 0
|
|
961
|
+
functions: 1
|
|
962
|
+
types: 0
|
|
963
|
+
processingTimeMs: 12
|
|
964
|
+
graph:
|
|
965
|
+
nodes:
|
|
966
|
+
- id: ast:src/index.ts:1:0
|
|
967
|
+
labels:
|
|
968
|
+
- Program
|
|
969
|
+
properties:
|
|
970
|
+
kind: Program
|
|
971
|
+
- id: ast:src/index.ts:3:2
|
|
972
|
+
labels:
|
|
973
|
+
- FunctionDeclaration
|
|
974
|
+
properties:
|
|
975
|
+
name: init
|
|
976
|
+
relationships:
|
|
977
|
+
- id: ast:src/index.ts:1:0_contains_ast:src/index.ts:3:2
|
|
978
|
+
type: contains
|
|
979
|
+
startNode: ast:src/index.ts:1:0
|
|
980
|
+
endNode: ast:src/index.ts:3:2
|
|
981
|
+
properties:
|
|
982
|
+
order: 1
|
|
983
|
+
'400':
|
|
984
|
+
$ref: '#/components/responses/BadRequest'
|
|
985
|
+
'401':
|
|
986
|
+
$ref: '#/components/responses/Unauthorized'
|
|
987
|
+
'403':
|
|
988
|
+
$ref: '#/components/responses/Forbidden'
|
|
989
|
+
'404':
|
|
990
|
+
$ref: '#/components/responses/NotFound'
|
|
991
|
+
'429':
|
|
992
|
+
$ref: '#/components/responses/TooManyRequests'
|
|
993
|
+
'500':
|
|
994
|
+
$ref: '#/components/responses/InternalError'
|
|
995
|
+
'502':
|
|
996
|
+
description: Bad Gateway
|
|
997
|
+
content:
|
|
998
|
+
application/json:
|
|
999
|
+
schema:
|
|
1000
|
+
$ref: '#/components/schemas/Error'
|
|
1001
|
+
/v1/graphs/supermodel:
|
|
1002
|
+
post:
|
|
1003
|
+
tags:
|
|
1004
|
+
- Data Plane
|
|
1005
|
+
summary: Supermodel graph
|
|
1006
|
+
description: Upload a zipped repository snapshot to generate the Supermodel Intermediate Representation (SIR) artifact bundle.
|
|
1007
|
+
operationId: generateSupermodelGraph
|
|
1008
|
+
security:
|
|
1009
|
+
- ApiKeyAuth: []
|
|
1010
|
+
parameters:
|
|
1011
|
+
- $ref: '#/components/parameters/IdempotencyKey'
|
|
1012
|
+
requestBody:
|
|
1013
|
+
required: true
|
|
1014
|
+
content:
|
|
1015
|
+
multipart/form-data:
|
|
1016
|
+
schema:
|
|
1017
|
+
type: object
|
|
1018
|
+
required:
|
|
1019
|
+
- file
|
|
1020
|
+
properties:
|
|
1021
|
+
file:
|
|
1022
|
+
type: string
|
|
1023
|
+
format: binary
|
|
1024
|
+
description: Zipped repository archive containing the code to analyze.
|
|
1025
|
+
x-codeSamples:
|
|
1026
|
+
- lang: cURL
|
|
1027
|
+
label: cURL
|
|
1028
|
+
source: |
|
|
1029
|
+
curl -X POST 'https://api.supermodeltools.com/v1/graphs/supermodel' \
|
|
1030
|
+
-H 'Idempotency-Key: <idempotency-key>' \
|
|
1031
|
+
-H 'X-Api-Key: <api-key>' \
|
|
1032
|
+
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
|
|
1033
|
+
- lang: javascript
|
|
1034
|
+
label: JavaScript (fetch)
|
|
1035
|
+
source: |
|
|
1036
|
+
import { readFile } from 'node:fs/promises';
|
|
1037
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
1038
|
+
const apiKey = '<api-key>';
|
|
1039
|
+
const idempotencyKey = '<idempotency-key>';
|
|
1040
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
1041
|
+
|
|
1042
|
+
const buffer = await readFile(archivePath);
|
|
1043
|
+
const form = new FormData();
|
|
1044
|
+
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
|
|
1045
|
+
|
|
1046
|
+
const res = await fetch(`${baseUrl}/v1/graphs/supermodel`, {
|
|
1047
|
+
method: 'POST',
|
|
1048
|
+
headers: {
|
|
1049
|
+
'Idempotency-Key': idempotencyKey,
|
|
1050
|
+
'X-Api-Key': apiKey
|
|
1051
|
+
},
|
|
1052
|
+
body: form
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
if (!res.ok) throw new Error(await res.text());
|
|
1056
|
+
console.log(await res.json());
|
|
1057
|
+
- lang: typescript
|
|
1058
|
+
label: TypeScript (SDK)
|
|
1059
|
+
source: |
|
|
1060
|
+
import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
|
|
1061
|
+
import { readFile } from 'node:fs/promises';
|
|
1062
|
+
|
|
1063
|
+
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
|
|
1064
|
+
const apiKey = '<api-key>';
|
|
1065
|
+
const idempotencyKey = '<idempotency-key>';
|
|
1066
|
+
const archivePath = '/path/to/your/repo-snapshot.zip';
|
|
1067
|
+
|
|
1068
|
+
const buffer = await readFile(archivePath);
|
|
1069
|
+
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
|
|
1070
|
+
|
|
1071
|
+
const configuration = new Configuration({ basePath: baseUrl });
|
|
1072
|
+
|
|
1073
|
+
const apiKeyOverride = async ({ init }) => ({
|
|
1074
|
+
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
|
|
1075
|
+
});
|
|
1076
|
+
|
|
1077
|
+
const api = new DefaultApi(configuration);
|
|
1078
|
+
const result = await api.generateSupermodelGraph(
|
|
1079
|
+
{ idempotencyKey, file: archiveBlob },
|
|
1080
|
+
apiKeyOverride
|
|
1081
|
+
);
|
|
1082
|
+
|
|
1083
|
+
console.log(result);
|
|
1084
|
+
- lang: java
|
|
1085
|
+
label: Java (generated client)
|
|
1086
|
+
source: |
|
|
1087
|
+
import org.openapitools.client.ApiClient;
|
|
1088
|
+
import org.openapitools.client.api.DefaultApi;
|
|
1089
|
+
|
|
1090
|
+
import java.io.File;
|
|
1091
|
+
|
|
1092
|
+
public class Example {
|
|
1093
|
+
public static void main(String[] args) throws Exception {
|
|
1094
|
+
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
|
|
1095
|
+
String apiKey = "<api-key>";
|
|
1096
|
+
String idempotencyKey = "<idempotency-key>";
|
|
1097
|
+
File archive = new File("/path/to/your/repo-snapshot.zip");
|
|
1098
|
+
|
|
1099
|
+
ApiClient client = new ApiClient();
|
|
1100
|
+
client.updateBaseUri(baseUrl);
|
|
1101
|
+
client.setRequestInterceptor(rb -> {
|
|
1102
|
+
rb.header("X-Api-Key", apiKey);
|
|
1103
|
+
});
|
|
1104
|
+
|
|
1105
|
+
DefaultApi api = new DefaultApi(client);
|
|
1106
|
+
api.generateSupermodelGraph(idempotencyKey, archive);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
- lang: python
|
|
1110
|
+
label: Python (generated client)
|
|
1111
|
+
source: |
|
|
1112
|
+
import os
|
|
1113
|
+
from supermodel_public_api import ApiClient, Configuration
|
|
1114
|
+
from supermodel_public_api.api.default_api import DefaultApi
|
|
1115
|
+
|
|
1116
|
+
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
|
|
1117
|
+
api_key = "<api-key>"
|
|
1118
|
+
idempotency_key = "<idempotency-key>"
|
|
1119
|
+
|
|
1120
|
+
configuration = Configuration(host=base_url)
|
|
1121
|
+
configuration.api_key["ApiKeyAuth"] = api_key
|
|
1122
|
+
|
|
1123
|
+
api_client = ApiClient(configuration)
|
|
1124
|
+
api = DefaultApi(api_client)
|
|
1125
|
+
|
|
1126
|
+
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
|
|
1127
|
+
payload = f.read()
|
|
1128
|
+
|
|
1129
|
+
result = api.generate_supermodel_graph(idempotency_key, file=payload)
|
|
1130
|
+
print(result)
|
|
1131
|
+
- lang: rust
|
|
1132
|
+
label: Rust (reqwest)
|
|
1133
|
+
source: |
|
|
1134
|
+
use bytes::Bytes;
|
|
1135
|
+
use reqwest::multipart::{Form, Part};
|
|
1136
|
+
|
|
1137
|
+
#[tokio::main]
|
|
1138
|
+
async fn main() -> anyhow::Result<()> {
|
|
1139
|
+
let base_url = std::env::var("API_BASE_URL")
|
|
1140
|
+
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
|
|
1141
|
+
let api_key = "<api-key>";
|
|
1142
|
+
let idempotency_key = "<idempotency-key>";
|
|
1143
|
+
|
|
1144
|
+
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
|
|
1145
|
+
let url = format!("{}/v1/graphs/supermodel", base_url.trim_end_matches('/'));
|
|
1146
|
+
|
|
1147
|
+
let file_part = Part::bytes(archive_bytes.to_vec())
|
|
1148
|
+
.file_name("repo.zip")
|
|
1149
|
+
.mime_str("application/zip")?;
|
|
1150
|
+
let form = Form::new().part("file", file_part);
|
|
1151
|
+
|
|
1152
|
+
let response = reqwest::Client::new()
|
|
1153
|
+
.post(url)
|
|
1154
|
+
.header("Idempotency-Key", idempotency_key)
|
|
1155
|
+
.header("X-Api-Key", api_key)
|
|
1156
|
+
.multipart(form)
|
|
1157
|
+
.send()
|
|
1158
|
+
.await?;
|
|
1159
|
+
let status = response.status();
|
|
1160
|
+
let body = response.bytes().await?;
|
|
1161
|
+
|
|
1162
|
+
if status.is_success() {
|
|
1163
|
+
println!("{}", String::from_utf8_lossy(&body));
|
|
1164
|
+
} else {
|
|
1165
|
+
anyhow::bail!(
|
|
1166
|
+
"Request failed ({}): {}",
|
|
1167
|
+
status.as_u16(),
|
|
1168
|
+
String::from_utf8_lossy(&body)
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
Ok(())
|
|
1173
|
+
}
|
|
1174
|
+
responses:
|
|
1175
|
+
'200':
|
|
1176
|
+
description: Supermodel IR document
|
|
1177
|
+
headers:
|
|
1178
|
+
X-Request-Id:
|
|
1179
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1180
|
+
X-API-Version:
|
|
1181
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1182
|
+
RateLimit-Limit:
|
|
1183
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1184
|
+
RateLimit-Remaining:
|
|
1185
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1186
|
+
RateLimit-Reset:
|
|
1187
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1188
|
+
X-Usage-Units:
|
|
1189
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1190
|
+
content:
|
|
1191
|
+
application/json:
|
|
1192
|
+
schema:
|
|
1193
|
+
$ref: '#/components/schemas/SupermodelIR'
|
|
1194
|
+
example:
|
|
1195
|
+
repo: supermodel/supermodel-public-api
|
|
1196
|
+
version: sir-2025-02-05
|
|
1197
|
+
schemaVersion: 1.2.0
|
|
1198
|
+
generatedAt: '2025-02-05 15:42:10.000000000 Z'
|
|
1199
|
+
summary:
|
|
1200
|
+
repoSizeBytes: 123456
|
|
1201
|
+
filesProcessed: 42
|
|
1202
|
+
classes: 8
|
|
1203
|
+
functions: 156
|
|
1204
|
+
types: 12
|
|
1205
|
+
primaryLanguage: typescript
|
|
1206
|
+
domains: 5
|
|
1207
|
+
graph:
|
|
1208
|
+
nodes:
|
|
1209
|
+
- id: src/index.ts
|
|
1210
|
+
labels:
|
|
1211
|
+
- File
|
|
1212
|
+
properties:
|
|
1213
|
+
path: src/index.ts
|
|
1214
|
+
name: index.ts
|
|
1215
|
+
language: typescript
|
|
1216
|
+
- id: fn:src/index.ts:main
|
|
1217
|
+
labels:
|
|
1218
|
+
- Function
|
|
1219
|
+
properties:
|
|
1220
|
+
name: main
|
|
1221
|
+
filePath: src/index.ts
|
|
1222
|
+
startLine: 10
|
|
1223
|
+
endLine: 25
|
|
1224
|
+
- id: fn:src/utils.ts:helper
|
|
1225
|
+
labels:
|
|
1226
|
+
- Function
|
|
1227
|
+
properties:
|
|
1228
|
+
name: helper
|
|
1229
|
+
filePath: src/utils.ts
|
|
1230
|
+
- id: domain:Core
|
|
1231
|
+
labels:
|
|
1232
|
+
- Domain
|
|
1233
|
+
properties:
|
|
1234
|
+
name: Core
|
|
1235
|
+
description: Core application logic
|
|
1236
|
+
- id: subdomain:Core:Initialization
|
|
1237
|
+
labels:
|
|
1238
|
+
- Subdomain
|
|
1239
|
+
properties:
|
|
1240
|
+
name: Initialization
|
|
1241
|
+
parentDomain: Core
|
|
1242
|
+
relationships:
|
|
1243
|
+
- id: src/index.ts_contains_fn:src/index.ts:main
|
|
1244
|
+
type: contains
|
|
1245
|
+
startNode: src/index.ts
|
|
1246
|
+
endNode: fn:src/index.ts:main
|
|
1247
|
+
- id: src/index.ts_imports_src/utils.ts
|
|
1248
|
+
type: imports
|
|
1249
|
+
startNode: src/index.ts
|
|
1250
|
+
endNode: src/utils.ts
|
|
1251
|
+
- id: fn:src/index.ts:main_calls_fn:src/utils.ts:helper
|
|
1252
|
+
type: calls
|
|
1253
|
+
startNode: fn:src/index.ts:main
|
|
1254
|
+
endNode: fn:src/utils.ts:helper
|
|
1255
|
+
- id: fn:src/index.ts:main_belongsTo_subdomain:Core:Initialization
|
|
1256
|
+
type: belongsTo
|
|
1257
|
+
startNode: fn:src/index.ts:main
|
|
1258
|
+
endNode: subdomain:Core:Initialization
|
|
1259
|
+
artifacts:
|
|
1260
|
+
- id: artifact-usage-summary
|
|
1261
|
+
kind: summary
|
|
1262
|
+
label: Usage Insights
|
|
1263
|
+
metadata:
|
|
1264
|
+
repoSizeBytes: 123456
|
|
1265
|
+
filesProcessed: 42
|
|
1266
|
+
functions: 156
|
|
1267
|
+
classes: 8
|
|
1268
|
+
- id: parse-graph
|
|
1269
|
+
kind: graph
|
|
1270
|
+
label: Parse Graph
|
|
1271
|
+
metadata:
|
|
1272
|
+
nodeCount: 150
|
|
1273
|
+
relationshipCount: 280
|
|
1274
|
+
- id: call-graph
|
|
1275
|
+
kind: graph
|
|
1276
|
+
label: Call Graph
|
|
1277
|
+
metadata:
|
|
1278
|
+
totalFunctions: 156
|
|
1279
|
+
totalCalls: 423
|
|
1280
|
+
- id: domain-classification
|
|
1281
|
+
kind: classification
|
|
1282
|
+
label: Domain Classification
|
|
1283
|
+
metadata:
|
|
1284
|
+
domainCount: 5
|
|
1285
|
+
relationshipCount: 8
|
|
1286
|
+
fileAssignments: 42
|
|
1287
|
+
functionAssignments: 120
|
|
1288
|
+
'400':
|
|
1289
|
+
$ref: '#/components/responses/BadRequest'
|
|
1290
|
+
'401':
|
|
1291
|
+
$ref: '#/components/responses/Unauthorized'
|
|
1292
|
+
'403':
|
|
1293
|
+
$ref: '#/components/responses/Forbidden'
|
|
1294
|
+
'429':
|
|
1295
|
+
$ref: '#/components/responses/TooManyRequests'
|
|
1296
|
+
'500':
|
|
1297
|
+
$ref: '#/components/responses/InternalError'
|
|
1298
|
+
'502':
|
|
1299
|
+
description: Bad Gateway
|
|
1300
|
+
content:
|
|
1301
|
+
application/json:
|
|
1302
|
+
schema:
|
|
1303
|
+
$ref: '#/components/schemas/Error'
|
|
1304
|
+
components:
|
|
1305
|
+
securitySchemes:
|
|
1306
|
+
ApiKeyAuth:
|
|
1307
|
+
type: apiKey
|
|
1308
|
+
in: header
|
|
1309
|
+
name: X-Api-Key
|
|
1310
|
+
description: API key issued by the control plane for accessing data plane resources.
|
|
1311
|
+
BearerAuth:
|
|
1312
|
+
type: http
|
|
1313
|
+
scheme: bearer
|
|
1314
|
+
description: HTTP Bearer authentication using an OAuth provider-issued access token presented via the Authorization header.
|
|
1315
|
+
StripeSecret:
|
|
1316
|
+
type: apiKey
|
|
1317
|
+
in: header
|
|
1318
|
+
name: Stripe-Secret
|
|
1319
|
+
description: Shared secret used to authorize Stripe webhook callbacks.
|
|
1320
|
+
parameters:
|
|
1321
|
+
IdempotencyKey:
|
|
1322
|
+
name: Idempotency-Key
|
|
1323
|
+
in: header
|
|
1324
|
+
required: true
|
|
1325
|
+
description: Unique identifier for this request for idempotency and tracing.
|
|
1326
|
+
schema:
|
|
1327
|
+
type: string
|
|
1328
|
+
headers:
|
|
1329
|
+
X-Request-Id:
|
|
1330
|
+
description: Unique request identifier echoed back from the Idempotency-Key header.
|
|
1331
|
+
schema:
|
|
1332
|
+
type: string
|
|
1333
|
+
X-API-Version:
|
|
1334
|
+
description: Semantic version of the API service handling the request.
|
|
1335
|
+
schema:
|
|
1336
|
+
type: string
|
|
1337
|
+
RateLimit-Limit:
|
|
1338
|
+
description: Maximum number of requests allowed in the current rate limit window.
|
|
1339
|
+
schema:
|
|
1340
|
+
type: integer
|
|
1341
|
+
format: int32
|
|
1342
|
+
RateLimit-Remaining:
|
|
1343
|
+
description: Remaining number of requests available in the current rate limit window.
|
|
1344
|
+
schema:
|
|
1345
|
+
type: integer
|
|
1346
|
+
format: int32
|
|
1347
|
+
RateLimit-Reset:
|
|
1348
|
+
description: UTC epoch seconds when the current rate limit window resets.
|
|
1349
|
+
schema:
|
|
1350
|
+
type: integer
|
|
1351
|
+
format: int64
|
|
1352
|
+
X-Usage-Units:
|
|
1353
|
+
description: Metered usage units consumed by this request.
|
|
1354
|
+
schema:
|
|
1355
|
+
type: number
|
|
1356
|
+
format: float
|
|
1357
|
+
responses:
|
|
1358
|
+
BadRequest:
|
|
1359
|
+
description: The request could not be processed because of a client error.
|
|
1360
|
+
headers:
|
|
1361
|
+
X-Request-Id:
|
|
1362
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1363
|
+
X-API-Version:
|
|
1364
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1365
|
+
RateLimit-Limit:
|
|
1366
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1367
|
+
RateLimit-Remaining:
|
|
1368
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1369
|
+
RateLimit-Reset:
|
|
1370
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1371
|
+
X-Usage-Units:
|
|
1372
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1373
|
+
content:
|
|
1374
|
+
application/json:
|
|
1375
|
+
schema:
|
|
1376
|
+
$ref: '#/components/schemas/Error'
|
|
1377
|
+
example:
|
|
1378
|
+
status: 400
|
|
1379
|
+
code: invalid_request
|
|
1380
|
+
message: Missing required query parameter 'repo'.
|
|
1381
|
+
timestamp: '2025-02-05 16:35:12.000000000 Z'
|
|
1382
|
+
requestId: req_01HZYJ9CE0ABCDEF1234
|
|
1383
|
+
details:
|
|
1384
|
+
- field: repo
|
|
1385
|
+
issue: This field is required.
|
|
1386
|
+
location: query
|
|
1387
|
+
Unauthorized:
|
|
1388
|
+
description: Authentication failed or was not provided.
|
|
1389
|
+
headers:
|
|
1390
|
+
X-Request-Id:
|
|
1391
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1392
|
+
X-API-Version:
|
|
1393
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1394
|
+
RateLimit-Limit:
|
|
1395
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1396
|
+
RateLimit-Remaining:
|
|
1397
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1398
|
+
RateLimit-Reset:
|
|
1399
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1400
|
+
X-Usage-Units:
|
|
1401
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1402
|
+
content:
|
|
1403
|
+
application/json:
|
|
1404
|
+
schema:
|
|
1405
|
+
$ref: '#/components/schemas/Error'
|
|
1406
|
+
example:
|
|
1407
|
+
status: 401
|
|
1408
|
+
code: unauthorized
|
|
1409
|
+
message: Provide a valid OAuth token to access this resource.
|
|
1410
|
+
timestamp: '2025-02-05 16:35:12.000000000 Z'
|
|
1411
|
+
requestId: req_01HZYJ9CE0ABCDEFXYZ1
|
|
1412
|
+
Forbidden:
|
|
1413
|
+
description: The authenticated principal lacks the required permissions.
|
|
1414
|
+
headers:
|
|
1415
|
+
X-Request-Id:
|
|
1416
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1417
|
+
X-API-Version:
|
|
1418
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1419
|
+
RateLimit-Limit:
|
|
1420
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1421
|
+
RateLimit-Remaining:
|
|
1422
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1423
|
+
RateLimit-Reset:
|
|
1424
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1425
|
+
X-Usage-Units:
|
|
1426
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1427
|
+
content:
|
|
1428
|
+
application/json:
|
|
1429
|
+
schema:
|
|
1430
|
+
$ref: '#/components/schemas/Error'
|
|
1431
|
+
example:
|
|
1432
|
+
status: 403
|
|
1433
|
+
code: forbidden
|
|
1434
|
+
message: The token lacks the required keys:write scope.
|
|
1435
|
+
timestamp: '2025-02-05 16:35:12.000000000 Z'
|
|
1436
|
+
requestId: req_01HZYJ9CE0ABCDEFFORB
|
|
1437
|
+
NotFound:
|
|
1438
|
+
description: The requested resource could not be found.
|
|
1439
|
+
headers:
|
|
1440
|
+
X-Request-Id:
|
|
1441
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1442
|
+
X-API-Version:
|
|
1443
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1444
|
+
RateLimit-Limit:
|
|
1445
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1446
|
+
RateLimit-Remaining:
|
|
1447
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1448
|
+
RateLimit-Reset:
|
|
1449
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1450
|
+
X-Usage-Units:
|
|
1451
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1452
|
+
content:
|
|
1453
|
+
application/json:
|
|
1454
|
+
schema:
|
|
1455
|
+
$ref: '#/components/schemas/Error'
|
|
1456
|
+
example:
|
|
1457
|
+
status: 404
|
|
1458
|
+
code: not_found
|
|
1459
|
+
message: API key ak_live_missing was not found.
|
|
1460
|
+
timestamp: '2025-02-05 16:35:12.000000000 Z'
|
|
1461
|
+
requestId: req_01HZYJ9CE0ABCDEFF404
|
|
1462
|
+
TooManyRequests:
|
|
1463
|
+
description: The rate limit for the resource has been exceeded.
|
|
1464
|
+
headers:
|
|
1465
|
+
X-Request-Id:
|
|
1466
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1467
|
+
X-API-Version:
|
|
1468
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1469
|
+
RateLimit-Limit:
|
|
1470
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1471
|
+
RateLimit-Remaining:
|
|
1472
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1473
|
+
RateLimit-Reset:
|
|
1474
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1475
|
+
X-Usage-Units:
|
|
1476
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1477
|
+
content:
|
|
1478
|
+
application/json:
|
|
1479
|
+
schema:
|
|
1480
|
+
$ref: '#/components/schemas/Error'
|
|
1481
|
+
example:
|
|
1482
|
+
status: 429
|
|
1483
|
+
code: rate_limit_exceeded
|
|
1484
|
+
message: Too many requests. Try again after the reset window.
|
|
1485
|
+
timestamp: '2025-02-05 16:35:12.000000000 Z'
|
|
1486
|
+
requestId: req_01HZYJ9CE0ABCDEFRATE
|
|
1487
|
+
InternalError:
|
|
1488
|
+
description: The server encountered an unexpected condition.
|
|
1489
|
+
headers:
|
|
1490
|
+
X-Request-Id:
|
|
1491
|
+
$ref: '#/components/headers/X-Request-Id'
|
|
1492
|
+
X-API-Version:
|
|
1493
|
+
$ref: '#/components/headers/X-API-Version'
|
|
1494
|
+
RateLimit-Limit:
|
|
1495
|
+
$ref: '#/components/headers/RateLimit-Limit'
|
|
1496
|
+
RateLimit-Remaining:
|
|
1497
|
+
$ref: '#/components/headers/RateLimit-Remaining'
|
|
1498
|
+
RateLimit-Reset:
|
|
1499
|
+
$ref: '#/components/headers/RateLimit-Reset'
|
|
1500
|
+
X-Usage-Units:
|
|
1501
|
+
$ref: '#/components/headers/X-Usage-Units'
|
|
1502
|
+
content:
|
|
1503
|
+
application/json:
|
|
1504
|
+
schema:
|
|
1505
|
+
$ref: '#/components/schemas/Error'
|
|
1506
|
+
example:
|
|
1507
|
+
status: 500
|
|
1508
|
+
code: internal_error
|
|
1509
|
+
message: Unexpected error processing request. Please retry.
|
|
1510
|
+
timestamp: '2025-02-05 16:35:12.000000000 Z'
|
|
1511
|
+
requestId: req_01HZYJ9CE0ABCDEFFAIL
|
|
1512
|
+
schemas:
|
|
1513
|
+
CodeGraphNode:
|
|
1514
|
+
type: object
|
|
1515
|
+
properties:
|
|
1516
|
+
id:
|
|
1517
|
+
type: string
|
|
1518
|
+
labels:
|
|
1519
|
+
type: array
|
|
1520
|
+
items:
|
|
1521
|
+
type: string
|
|
1522
|
+
properties:
|
|
1523
|
+
type: object
|
|
1524
|
+
additionalProperties: true
|
|
1525
|
+
required:
|
|
1526
|
+
- id
|
|
1527
|
+
CodeGraphRelationship:
|
|
1528
|
+
type: object
|
|
1529
|
+
properties:
|
|
1530
|
+
id:
|
|
1531
|
+
type: string
|
|
1532
|
+
type:
|
|
1533
|
+
type: string
|
|
1534
|
+
startNode:
|
|
1535
|
+
type: string
|
|
1536
|
+
endNode:
|
|
1537
|
+
type: string
|
|
1538
|
+
properties:
|
|
1539
|
+
type: object
|
|
1540
|
+
additionalProperties: true
|
|
1541
|
+
required:
|
|
1542
|
+
- id
|
|
1543
|
+
- type
|
|
1544
|
+
- startNode
|
|
1545
|
+
- endNode
|
|
1546
|
+
CodeGraphStats:
|
|
1547
|
+
type: object
|
|
1548
|
+
properties:
|
|
1549
|
+
filesProcessed:
|
|
1550
|
+
type: integer
|
|
1551
|
+
format: int64
|
|
1552
|
+
classes:
|
|
1553
|
+
type: integer
|
|
1554
|
+
format: int64
|
|
1555
|
+
functions:
|
|
1556
|
+
type: integer
|
|
1557
|
+
format: int64
|
|
1558
|
+
types:
|
|
1559
|
+
type: integer
|
|
1560
|
+
format: int64
|
|
1561
|
+
processingTimeMs:
|
|
1562
|
+
type: number
|
|
1563
|
+
CodeGraphEnvelope:
|
|
1564
|
+
type: object
|
|
1565
|
+
properties:
|
|
1566
|
+
generatedAt:
|
|
1567
|
+
type: string
|
|
1568
|
+
format: date-time
|
|
1569
|
+
message:
|
|
1570
|
+
type: string
|
|
1571
|
+
stats:
|
|
1572
|
+
$ref: '#/components/schemas/CodeGraphStats'
|
|
1573
|
+
graph:
|
|
1574
|
+
type: object
|
|
1575
|
+
properties:
|
|
1576
|
+
nodes:
|
|
1577
|
+
type: array
|
|
1578
|
+
items:
|
|
1579
|
+
$ref: '#/components/schemas/CodeGraphNode'
|
|
1580
|
+
relationships:
|
|
1581
|
+
type: array
|
|
1582
|
+
items:
|
|
1583
|
+
$ref: '#/components/schemas/CodeGraphRelationship'
|
|
1584
|
+
required:
|
|
1585
|
+
- nodes
|
|
1586
|
+
- relationships
|
|
1587
|
+
required:
|
|
1588
|
+
- graph
|
|
1589
|
+
Error:
|
|
1590
|
+
type: object
|
|
1591
|
+
description: Standardized error payload returned by the API.
|
|
1592
|
+
required:
|
|
1593
|
+
- status
|
|
1594
|
+
- code
|
|
1595
|
+
- message
|
|
1596
|
+
- timestamp
|
|
1597
|
+
properties:
|
|
1598
|
+
status:
|
|
1599
|
+
type: integer
|
|
1600
|
+
format: int32
|
|
1601
|
+
description: HTTP status code associated with the error.
|
|
1602
|
+
minimum: 100
|
|
1603
|
+
maximum: 599
|
|
1604
|
+
code:
|
|
1605
|
+
type: string
|
|
1606
|
+
description: Stable, machine-readable error identifier.
|
|
1607
|
+
message:
|
|
1608
|
+
type: string
|
|
1609
|
+
description: Human-readable description of the error.
|
|
1610
|
+
timestamp:
|
|
1611
|
+
type: string
|
|
1612
|
+
format: date-time
|
|
1613
|
+
description: ISO-8601 timestamp indicating when the error occurred.
|
|
1614
|
+
requestId:
|
|
1615
|
+
type: string
|
|
1616
|
+
description: Correlation identifier for tracing the failing request.
|
|
1617
|
+
details:
|
|
1618
|
+
type: array
|
|
1619
|
+
description: Optional list of contextual error details.
|
|
1620
|
+
items:
|
|
1621
|
+
type: object
|
|
1622
|
+
required:
|
|
1623
|
+
- field
|
|
1624
|
+
- issue
|
|
1625
|
+
properties:
|
|
1626
|
+
field:
|
|
1627
|
+
type: string
|
|
1628
|
+
description: Name of the field or parameter related to the error.
|
|
1629
|
+
issue:
|
|
1630
|
+
type: string
|
|
1631
|
+
description: Description of the specific issue encountered.
|
|
1632
|
+
location:
|
|
1633
|
+
type: string
|
|
1634
|
+
description: Where the field resides (e.g., query, path, body).
|
|
1635
|
+
SupermodelArtifact:
|
|
1636
|
+
type: object
|
|
1637
|
+
required:
|
|
1638
|
+
- id
|
|
1639
|
+
- kind
|
|
1640
|
+
- label
|
|
1641
|
+
properties:
|
|
1642
|
+
id:
|
|
1643
|
+
type: string
|
|
1644
|
+
description: Unique identifier for the artifact.
|
|
1645
|
+
kind:
|
|
1646
|
+
type: string
|
|
1647
|
+
description: Artifact kind such as graph, summary, or embedding.
|
|
1648
|
+
label:
|
|
1649
|
+
type: string
|
|
1650
|
+
description: Human-readable name for the artifact.
|
|
1651
|
+
metadata:
|
|
1652
|
+
type: object
|
|
1653
|
+
description: Additional metadata for consuming the artifact.
|
|
1654
|
+
additionalProperties: true
|
|
1655
|
+
SupermodelIR:
|
|
1656
|
+
type: object
|
|
1657
|
+
required:
|
|
1658
|
+
- repo
|
|
1659
|
+
- version
|
|
1660
|
+
- schemaVersion
|
|
1661
|
+
- generatedAt
|
|
1662
|
+
- graph
|
|
1663
|
+
properties:
|
|
1664
|
+
repo:
|
|
1665
|
+
type: string
|
|
1666
|
+
description: Repository slug the IR was generated from.
|
|
1667
|
+
version:
|
|
1668
|
+
type: string
|
|
1669
|
+
description: Version identifier for the IR content.
|
|
1670
|
+
schemaVersion:
|
|
1671
|
+
type: string
|
|
1672
|
+
description: Version of the IR schema.
|
|
1673
|
+
generatedAt:
|
|
1674
|
+
type: string
|
|
1675
|
+
format: date-time
|
|
1676
|
+
description: Timestamp when the IR was generated.
|
|
1677
|
+
summary:
|
|
1678
|
+
type: object
|
|
1679
|
+
description: High-level metadata and summary insights including filesProcessed, classes, functions, types, primaryLanguage, and domains count.
|
|
1680
|
+
additionalProperties: true
|
|
1681
|
+
graph:
|
|
1682
|
+
type: object
|
|
1683
|
+
description: Unified code graph containing all nodes and relationships.
|
|
1684
|
+
properties:
|
|
1685
|
+
nodes:
|
|
1686
|
+
type: array
|
|
1687
|
+
description: All nodes from parse graph, call graph, and domain classification.
|
|
1688
|
+
items:
|
|
1689
|
+
$ref: '#/components/schemas/CodeGraphNode'
|
|
1690
|
+
relationships:
|
|
1691
|
+
type: array
|
|
1692
|
+
description: All relationships including contains, imports, calls, and belongsTo.
|
|
1693
|
+
items:
|
|
1694
|
+
$ref: '#/components/schemas/CodeGraphRelationship'
|
|
1695
|
+
required:
|
|
1696
|
+
- nodes
|
|
1697
|
+
- relationships
|
|
1698
|
+
artifacts:
|
|
1699
|
+
type: array
|
|
1700
|
+
description: Per-source statistics and metadata for parse graph, call graph, and domain classification.
|
|
1701
|
+
items:
|
|
1702
|
+
$ref: '#/components/schemas/SupermodelArtifact'
|
|
1703
|
+
DomainClassificationResponse:
|
|
1704
|
+
type: object
|
|
1705
|
+
properties:
|
|
1706
|
+
runId:
|
|
1707
|
+
type: string
|
|
1708
|
+
description: Unique identifier for this classification run
|
|
1709
|
+
domains:
|
|
1710
|
+
type: array
|
|
1711
|
+
items:
|
|
1712
|
+
$ref: '#/components/schemas/DomainSummary'
|
|
1713
|
+
description: Array of primary domain entities
|
|
1714
|
+
relationships:
|
|
1715
|
+
type: array
|
|
1716
|
+
items:
|
|
1717
|
+
$ref: '#/components/schemas/DomainRelationship'
|
|
1718
|
+
description: High-level relationships between domains/subdomains
|
|
1719
|
+
fileAssignments:
|
|
1720
|
+
type: array
|
|
1721
|
+
items:
|
|
1722
|
+
$ref: '#/components/schemas/DomainFileAssignment'
|
|
1723
|
+
description: Mapping of files to domains
|
|
1724
|
+
functionAssignments:
|
|
1725
|
+
type: array
|
|
1726
|
+
items:
|
|
1727
|
+
$ref: '#/components/schemas/DomainFunctionAssignment'
|
|
1728
|
+
description: Mapping of functions to subdomains
|
|
1729
|
+
unassignedFunctions:
|
|
1730
|
+
type: array
|
|
1731
|
+
items:
|
|
1732
|
+
$ref: '#/components/schemas/UnassignedFunction'
|
|
1733
|
+
description: Functions that could not be assigned to a domain/subdomain
|
|
1734
|
+
classAssignments:
|
|
1735
|
+
type: array
|
|
1736
|
+
items:
|
|
1737
|
+
$ref: '#/components/schemas/DomainClassAssignment'
|
|
1738
|
+
description: Mapping of classes to domains
|
|
1739
|
+
functionDescriptions:
|
|
1740
|
+
type: array
|
|
1741
|
+
items:
|
|
1742
|
+
$ref: '#/components/schemas/FunctionDescription'
|
|
1743
|
+
description: Optional enriched descriptions per function
|
|
1744
|
+
stats:
|
|
1745
|
+
$ref: '#/components/schemas/ClassificationStats'
|
|
1746
|
+
required:
|
|
1747
|
+
- runId
|
|
1748
|
+
- domains
|
|
1749
|
+
- relationships
|
|
1750
|
+
- fileAssignments
|
|
1751
|
+
- functionAssignments
|
|
1752
|
+
- unassignedFunctions
|
|
1753
|
+
- classAssignments
|
|
1754
|
+
- stats
|
|
1755
|
+
DomainSummary:
|
|
1756
|
+
type: object
|
|
1757
|
+
properties:
|
|
1758
|
+
name:
|
|
1759
|
+
type: string
|
|
1760
|
+
description: Domain name (e.g., BillingAccount)
|
|
1761
|
+
descriptionSummary:
|
|
1762
|
+
type: string
|
|
1763
|
+
description: Human-readable description of the domain
|
|
1764
|
+
keyFiles:
|
|
1765
|
+
type: array
|
|
1766
|
+
items:
|
|
1767
|
+
type: string
|
|
1768
|
+
description: Representative files backing the domain
|
|
1769
|
+
responsibilities:
|
|
1770
|
+
type: array
|
|
1771
|
+
items:
|
|
1772
|
+
type: string
|
|
1773
|
+
description: Key responsibilities/concerns of the domain
|
|
1774
|
+
subdomains:
|
|
1775
|
+
type: array
|
|
1776
|
+
items:
|
|
1777
|
+
$ref: '#/components/schemas/SubdomainSummary'
|
|
1778
|
+
description: Subdomains for this domain
|
|
1779
|
+
required:
|
|
1780
|
+
- name
|
|
1781
|
+
- descriptionSummary
|
|
1782
|
+
- keyFiles
|
|
1783
|
+
- responsibilities
|
|
1784
|
+
- subdomains
|
|
1785
|
+
SubdomainSummary:
|
|
1786
|
+
type: object
|
|
1787
|
+
properties:
|
|
1788
|
+
name:
|
|
1789
|
+
type: string
|
|
1790
|
+
description: Subdomain name
|
|
1791
|
+
descriptionSummary:
|
|
1792
|
+
type: string
|
|
1793
|
+
description: Concise description of the subdomain
|
|
1794
|
+
required:
|
|
1795
|
+
- name
|
|
1796
|
+
- descriptionSummary
|
|
1797
|
+
DomainRelationship:
|
|
1798
|
+
type: object
|
|
1799
|
+
properties:
|
|
1800
|
+
from:
|
|
1801
|
+
type: string
|
|
1802
|
+
description: Source domain or subdomain name/id
|
|
1803
|
+
to:
|
|
1804
|
+
type: string
|
|
1805
|
+
description: Target domain or subdomain name/id
|
|
1806
|
+
type:
|
|
1807
|
+
type: string
|
|
1808
|
+
description: Relationship type (e.g., aggregates, dependsOn, relatesTo)
|
|
1809
|
+
strength:
|
|
1810
|
+
type: number
|
|
1811
|
+
description: Numeric strength/weight (0-1 or small integer)
|
|
1812
|
+
reason:
|
|
1813
|
+
type: string
|
|
1814
|
+
description: Optional explanation for the relationship
|
|
1815
|
+
required:
|
|
1816
|
+
- from
|
|
1817
|
+
- to
|
|
1818
|
+
- type
|
|
1819
|
+
- strength
|
|
1820
|
+
DomainFileAssignment:
|
|
1821
|
+
type: object
|
|
1822
|
+
properties:
|
|
1823
|
+
filePath:
|
|
1824
|
+
type: string
|
|
1825
|
+
description: Repository-relative file path
|
|
1826
|
+
domainName:
|
|
1827
|
+
type: string
|
|
1828
|
+
description: Assigned domain
|
|
1829
|
+
required:
|
|
1830
|
+
- filePath
|
|
1831
|
+
- domainName
|
|
1832
|
+
DomainFunctionAssignment:
|
|
1833
|
+
type: object
|
|
1834
|
+
properties:
|
|
1835
|
+
functionId:
|
|
1836
|
+
type: string
|
|
1837
|
+
description: Stable function identifier (matching codegraph/function models)
|
|
1838
|
+
subdomainName:
|
|
1839
|
+
type: string
|
|
1840
|
+
description: Subdomain assigned to the function
|
|
1841
|
+
parentDomain:
|
|
1842
|
+
type: string
|
|
1843
|
+
description: Optional parent domain containing the subdomain
|
|
1844
|
+
required:
|
|
1845
|
+
- functionId
|
|
1846
|
+
- subdomainName
|
|
1847
|
+
UnassignedFunction:
|
|
1848
|
+
type: object
|
|
1849
|
+
properties:
|
|
1850
|
+
functionId:
|
|
1851
|
+
type: string
|
|
1852
|
+
description: Function that could not be assigned
|
|
1853
|
+
reason:
|
|
1854
|
+
type: string
|
|
1855
|
+
description: Reason it was left unassigned
|
|
1856
|
+
required:
|
|
1857
|
+
- functionId
|
|
1858
|
+
- reason
|
|
1859
|
+
DomainClassAssignment:
|
|
1860
|
+
type: object
|
|
1861
|
+
properties:
|
|
1862
|
+
classId:
|
|
1863
|
+
type: string
|
|
1864
|
+
description: Class identifier
|
|
1865
|
+
domainName:
|
|
1866
|
+
type: string
|
|
1867
|
+
description: Assigned domain
|
|
1868
|
+
required:
|
|
1869
|
+
- classId
|
|
1870
|
+
- domainName
|
|
1871
|
+
FunctionDescription:
|
|
1872
|
+
type: object
|
|
1873
|
+
properties:
|
|
1874
|
+
functionId:
|
|
1875
|
+
type: string
|
|
1876
|
+
description: Function identifier
|
|
1877
|
+
descriptionSummary:
|
|
1878
|
+
type: string
|
|
1879
|
+
description: Short summary of behavior
|
|
1880
|
+
domainName:
|
|
1881
|
+
type: string
|
|
1882
|
+
description: Optional domain/subdomain association
|
|
1883
|
+
required:
|
|
1884
|
+
- functionId
|
|
1885
|
+
- descriptionSummary
|
|
1886
|
+
ClassificationStats:
|
|
1887
|
+
type: object
|
|
1888
|
+
properties:
|
|
1889
|
+
domainCount:
|
|
1890
|
+
type: integer
|
|
1891
|
+
description: Number of domains discovered
|
|
1892
|
+
relationshipCount:
|
|
1893
|
+
type: integer
|
|
1894
|
+
description: Number of relationships
|
|
1895
|
+
fileAssignments:
|
|
1896
|
+
type: integer
|
|
1897
|
+
description: Count of file assignments
|
|
1898
|
+
functionAssignments:
|
|
1899
|
+
type: integer
|
|
1900
|
+
description: Count of function assignments
|
|
1901
|
+
unassignedFunctions:
|
|
1902
|
+
type: integer
|
|
1903
|
+
description: Count of unassigned functions
|
|
1904
|
+
classAssignments:
|
|
1905
|
+
type: integer
|
|
1906
|
+
description: Count of class assignments
|
|
1907
|
+
required:
|
|
1908
|
+
- domainCount
|
|
1909
|
+
- relationshipCount
|
|
1910
|
+
- fileAssignments
|
|
1911
|
+
- functionAssignments
|
|
1912
|
+
- unassignedFunctions
|
|
1913
|
+
- classAssignments
|