@labelbox/rl-sdk 0.0.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 (64) hide show
  1. package/README.md +90 -0
  2. package/dist/client-options.d.ts +39 -0
  3. package/dist/client-options.js +29 -0
  4. package/dist/generated/client/client.gen.d.ts +2 -0
  5. package/dist/generated/client/client.gen.js +216 -0
  6. package/dist/generated/client/index.d.ts +8 -0
  7. package/dist/generated/client/index.js +6 -0
  8. package/dist/generated/client/types.gen.d.ts +120 -0
  9. package/dist/generated/client/types.gen.js +2 -0
  10. package/dist/generated/client/utils.gen.d.ts +37 -0
  11. package/dist/generated/client/utils.gen.js +228 -0
  12. package/dist/generated/client.gen.d.ts +12 -0
  13. package/dist/generated/client.gen.js +3 -0
  14. package/dist/generated/core/auth.gen.d.ts +18 -0
  15. package/dist/generated/core/auth.gen.js +14 -0
  16. package/dist/generated/core/bodySerializer.gen.d.ts +25 -0
  17. package/dist/generated/core/bodySerializer.gen.js +57 -0
  18. package/dist/generated/core/params.gen.d.ts +43 -0
  19. package/dist/generated/core/params.gen.js +100 -0
  20. package/dist/generated/core/pathSerializer.gen.d.ts +33 -0
  21. package/dist/generated/core/pathSerializer.gen.js +106 -0
  22. package/dist/generated/core/queryKeySerializer.gen.d.ts +18 -0
  23. package/dist/generated/core/queryKeySerializer.gen.js +92 -0
  24. package/dist/generated/core/serverSentEvents.gen.d.ts +71 -0
  25. package/dist/generated/core/serverSentEvents.gen.js +132 -0
  26. package/dist/generated/core/types.gen.d.ts +78 -0
  27. package/dist/generated/core/types.gen.js +2 -0
  28. package/dist/generated/core/utils.gen.d.ts +19 -0
  29. package/dist/generated/core/utils.gen.js +87 -0
  30. package/dist/generated/index.d.ts +2 -0
  31. package/dist/generated/index.js +2 -0
  32. package/dist/generated/sdk.gen.d.ts +3054 -0
  33. package/dist/generated/sdk.gen.js +5962 -0
  34. package/dist/generated/types.gen.d.ts +39711 -0
  35. package/dist/generated/types.gen.js +2 -0
  36. package/dist/index.d.ts +21 -0
  37. package/dist/index.js +39 -0
  38. package/dist/nesting.d.ts +18 -0
  39. package/dist/nesting.js +75 -0
  40. package/dist/reference/concepts-reference.generated.d.ts +9 -0
  41. package/dist/reference/concepts-reference.generated.js +356 -0
  42. package/dist/reference/concepts-schema.d.ts +16 -0
  43. package/dist/reference/concepts-schema.js +39 -0
  44. package/dist/reference/concepts.d.ts +15 -0
  45. package/dist/reference/concepts.js +354 -0
  46. package/dist/reference/domains.d.ts +65 -0
  47. package/dist/reference/domains.js +32 -0
  48. package/dist/reference/recipes-reference.generated.d.ts +11 -0
  49. package/dist/reference/recipes-reference.generated.js +11415 -0
  50. package/dist/reference/recipes-schema.d.ts +676 -0
  51. package/dist/reference/recipes-schema.js +406 -0
  52. package/dist/reference/resources-reference.generated.d.ts +11 -0
  53. package/dist/reference/resources-reference.generated.js +7174 -0
  54. package/dist/reference/resources-schema.d.ts +78 -0
  55. package/dist/reference/resources-schema.js +71 -0
  56. package/dist/reference/schema.d.ts +153 -0
  57. package/dist/reference/schema.js +151 -0
  58. package/dist/reference/sdk-reference.generated.d.ts +10 -0
  59. package/dist/reference/sdk-reference.generated.js +65703 -0
  60. package/dist/reference/tutorials.d.ts +76 -0
  61. package/dist/reference/tutorials.js +65 -0
  62. package/dist/session-events.d.ts +92 -0
  63. package/dist/session-events.js +213 -0
  64. package/package.json +126 -0
@@ -0,0 +1,2 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ export {};
@@ -0,0 +1,21 @@
1
+ import { type RecursionClientOptions } from './client-options.js';
2
+ import { Recursion } from './generated/sdk.gen.js';
3
+ export { DEFAULT_BASE_URL, type RecursionClientOptions } from './client-options.js';
4
+ export * from './generated/index.js';
5
+ /**
6
+ * Server-sent events are the one managed-agents response shape the generated
7
+ * client cannot carry, so the session event stream is hand-written. See
8
+ * `session-events.ts` for why it is not generated.
9
+ */
10
+ export { ManagedAgentSessionStreamError, type ManagedAgentSessionStreamEvent, type ManagedAgentSessionStreamParams, streamManagedAgentSessionEvents, } from './session-events.js';
11
+ /**
12
+ * Construct an authenticated `Recursion` client.
13
+ *
14
+ * @example
15
+ * const rl = createRecursionClient({ apiKey: process.env.LABELBOX_API_KEY! });
16
+ * const job = await rl.synthesizers.create({
17
+ * environmentId: 'env_abc',
18
+ * body: { name: 'Variant generator', systemPrompt: '…', runConfigVersionId: 'rcv_…' },
19
+ * });
20
+ */
21
+ export declare function createRecursionClient(options: RecursionClientOptions): Recursion;
package/dist/index.js ADDED
@@ -0,0 +1,39 @@
1
+ // Public entry point for the rl-gym TypeScript SDK.
2
+ //
3
+ // The `Recursion` class and every namespace/method on it, plus the request/response
4
+ // types, are generated from the backend OpenAPI spec by `@hey-api/openapi-ts`
5
+ // (see `openapi-ts.config.ts`). This file is the only hand-written surface: it
6
+ // re-exports the generated client and adds a small constructor that wires auth +
7
+ // base URL. It does not grow as operations are added.
8
+ import { DEFAULT_BASE_URL } from './client-options.js';
9
+ import { createClient, createConfig } from './generated/client/index.js';
10
+ import { Recursion } from './generated/sdk.gen.js';
11
+ export { DEFAULT_BASE_URL } from './client-options.js';
12
+ export * from './generated/index.js';
13
+ /**
14
+ * Server-sent events are the one managed-agents response shape the generated
15
+ * client cannot carry, so the session event stream is hand-written. See
16
+ * `session-events.ts` for why it is not generated.
17
+ */
18
+ export { ManagedAgentSessionStreamError, streamManagedAgentSessionEvents, } from './session-events.js';
19
+ /**
20
+ * Construct an authenticated `Recursion` client.
21
+ *
22
+ * @example
23
+ * const rl = createRecursionClient({ apiKey: process.env.LABELBOX_API_KEY! });
24
+ * const job = await rl.synthesizers.create({
25
+ * environmentId: 'env_abc',
26
+ * body: { name: 'Variant generator', systemPrompt: '…', runConfigVersionId: 'rcv_…' },
27
+ * });
28
+ */
29
+ export function createRecursionClient(options) {
30
+ const client = createClient(createConfig({
31
+ baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
32
+ // Surface non-2xx responses as thrown errors so callers can use plain
33
+ // `await` + try/catch instead of inspecting an error field.
34
+ throwOnError: true,
35
+ // biome-ignore lint/style/useNamingConvention: HTTP header names are not camelCase.
36
+ headers: { ...options.headers, Authorization: `Bearer ${options.apiKey}` },
37
+ }));
38
+ return new Recursion({ client });
39
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * camelCase → kebab-case. Shared by the CLI (command + flag names) and the
3
+ * reference-doc generator (CLI example flags) so both spell names identically.
4
+ */
5
+ export declare function kebab(value: string): string;
6
+ /**
7
+ * Validate the declared SDK paths: every segment must be a camelCase identifier
8
+ * and no two operations may share the same path. Throws on the first problem —
9
+ * a codegen-time guard against malformed or shadowing routes.
10
+ */
11
+ export declare function validateSdkPaths(pathsByOperationId: Map<string, string[]>): void;
12
+ /**
13
+ * Scan a parsed OpenAPI spec for opted-in operations and return their declared
14
+ * SDK call paths keyed by operationId. An operation is opted in iff it carries
15
+ * an `x-sdk-path` array (emitted by the backend `@SdkRoute(...)` decorator). The
16
+ * collected paths are validated (unique, valid segments) before returning.
17
+ */
18
+ export declare function collectSdkPaths(spec: unknown): Map<string, string[]>;
@@ -0,0 +1,75 @@
1
+ // The SDK/CLI surface is declared at the source: each backend handler that
2
+ // should be generated carries `@SdkRoute(...segments)`, which emits an
3
+ // `x-sdk-path` OpenAPI extension. This module reads those declared paths from
4
+ // the spec and is the single source of truth shared by the hey-api codegen
5
+ // config (`openapi-ts.config.ts`) and the SDK reference-doc generator
6
+ // (`dx sdk:generate`), so the generated client and its docs can never disagree.
7
+ //
8
+ // There is no heuristic and no per-operation table here — the path comes
9
+ // straight from the decorator. Operations WITHOUT an `x-sdk-path` are not
10
+ // generated at all (that is also how an endpoint is excluded).
11
+ /**
12
+ * camelCase → kebab-case. Shared by the CLI (command + flag names) and the
13
+ * reference-doc generator (CLI example flags) so both spell names identically.
14
+ */
15
+ export function kebab(value) {
16
+ return value.replace(/([a-z0-9])([A-Z])/gu, '$1-$2').toLowerCase();
17
+ }
18
+ const SEGMENT = /^[a-z][A-Za-z0-9]*$/u;
19
+ const HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete'];
20
+ function isRecord(value) {
21
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
22
+ }
23
+ /**
24
+ * Validate the declared SDK paths: every segment must be a camelCase identifier
25
+ * and no two operations may share the same path. Throws on the first problem —
26
+ * a codegen-time guard against malformed or shadowing routes.
27
+ */
28
+ export function validateSdkPaths(pathsByOperationId) {
29
+ const seen = new Map();
30
+ for (const [operationId, path] of pathsByOperationId) {
31
+ if (path.length === 0) {
32
+ throw new Error(`sdk-ts: operation "${operationId}" has an empty x-sdk-path.`);
33
+ }
34
+ for (const segment of path) {
35
+ if (!SEGMENT.test(segment)) {
36
+ throw new Error(`sdk-ts: operation "${operationId}" has invalid x-sdk-path segment "${segment}" ` +
37
+ '(each segment must be a camelCase identifier).');
38
+ }
39
+ }
40
+ const key = path.join('.');
41
+ const prior = seen.get(key);
42
+ if (prior !== undefined) {
43
+ throw new Error(`sdk-ts: "${operationId}" and "${prior}" both declare rl.${key}(). Change one @SdkRoute.`);
44
+ }
45
+ seen.set(key, operationId);
46
+ }
47
+ }
48
+ /**
49
+ * Scan a parsed OpenAPI spec for opted-in operations and return their declared
50
+ * SDK call paths keyed by operationId. An operation is opted in iff it carries
51
+ * an `x-sdk-path` array (emitted by the backend `@SdkRoute(...)` decorator). The
52
+ * collected paths are validated (unique, valid segments) before returning.
53
+ */
54
+ export function collectSdkPaths(spec) {
55
+ // biome-ignore lint/complexity/useLiteralKeys: spec is Record<string, unknown>; noPropertyAccessFromIndexSignature requires bracket access
56
+ const paths = isRecord(spec) && isRecord(spec['paths']) ? spec['paths'] : {};
57
+ const result = new Map();
58
+ for (const methods of Object.values(paths)) {
59
+ if (!isRecord(methods))
60
+ continue;
61
+ for (const method of HTTP_METHODS) {
62
+ const op = methods[method];
63
+ if (!isRecord(op))
64
+ continue;
65
+ const sdkPath = op['x-sdk-path'];
66
+ // biome-ignore lint/complexity/useLiteralKeys: op is Record<string, unknown>; noPropertyAccessFromIndexSignature requires bracket access
67
+ const operationId = op['operationId'];
68
+ if (!Array.isArray(sdkPath) || typeof operationId !== 'string')
69
+ continue;
70
+ result.set(operationId, sdkPath.filter((segment) => typeof segment === 'string'));
71
+ }
72
+ }
73
+ validateSdkPaths(result);
74
+ return result;
75
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AUTO-GENERATED by 'yarn dx concepts:generate'.
3
+ * Do not edit manually — changes will be overwritten.
4
+ *
5
+ * Explanation-layer concept pages, keyed by id (= the markdown filename stem).
6
+ * Source of truth: the frontmatter of `frontend/public/docs/concepts/*.md`.
7
+ */
8
+ import type { ConceptReferenceEntry } from './concepts-schema.js';
9
+ export declare const CONCEPT_REFERENCE: Record<string, ConceptReferenceEntry>;
@@ -0,0 +1,356 @@
1
+ /**
2
+ * AUTO-GENERATED by 'yarn dx concepts:generate'.
3
+ * Do not edit manually — changes will be overwritten.
4
+ *
5
+ * Explanation-layer concept pages, keyed by id (= the markdown filename stem).
6
+ * Source of truth: the frontmatter of `frontend/public/docs/concepts/*.md`.
7
+ */
8
+ export const CONCEPT_REFERENCE = {
9
+ 'anatomy-of-a-problem-version': {
10
+ id: 'anatomy-of-a-problem-version',
11
+ title: 'Anatomy of a problem version',
12
+ domain: 'problems',
13
+ related: [
14
+ 'concept:problem-lifecycle',
15
+ 'concept:run-config-roles',
16
+ 'resource:problem-versions',
17
+ 'resource:problems',
18
+ ],
19
+ },
20
+ 'authentication-and-access': {
21
+ id: 'authentication-and-access',
22
+ title: 'Authentication and access',
23
+ domain: 'platform',
24
+ related: ['concept:the-permission-model', 'concept:organizations-and-users'],
25
+ },
26
+ computes: {
27
+ id: 'computes',
28
+ title: 'Computes',
29
+ domain: 'run-configs',
30
+ related: [
31
+ 'concept:run-config-anatomy',
32
+ 'concept:snapshot-solvers-on-compute',
33
+ 'resource:computes',
34
+ ],
35
+ },
36
+ 'container-images-and-the-marketplace': {
37
+ id: 'container-images-and-the-marketplace',
38
+ title: 'Container images and the marketplace',
39
+ domain: 'run-configs',
40
+ related: [
41
+ 'concept:computes',
42
+ 'recipe:browse-images-and-models',
43
+ 'resource:images',
44
+ 'resource:marketplace',
45
+ 'resource:models',
46
+ ],
47
+ },
48
+ 'cost-accounting': {
49
+ id: 'cost-accounting',
50
+ title: 'How cost is accounted',
51
+ domain: 'cost',
52
+ related: [
53
+ 'resource:cost-limits',
54
+ 'resource:problem-runs',
55
+ 'resource:evaluations',
56
+ 'concept:cost-limits-and-budgets',
57
+ 'concept:the-cost-explorer',
58
+ ],
59
+ },
60
+ 'cost-limits-and-budgets': {
61
+ id: 'cost-limits-and-budgets',
62
+ title: 'Cost limits and budgets',
63
+ domain: 'cost',
64
+ related: [
65
+ 'recipe:set-a-per-problem-cost-limit',
66
+ 'recipe:set-an-environment-cost-limit',
67
+ 'recipe:remove-a-cost-limit',
68
+ 'resource:cost-limits',
69
+ 'concept:cost-accounting',
70
+ ],
71
+ },
72
+ 'designing-an-evaluation': {
73
+ id: 'designing-an-evaluation',
74
+ title: 'Designing an evaluation',
75
+ domain: 'evaluations',
76
+ related: [
77
+ 'concept:evaluation-vs-problem-run',
78
+ 'recipe:run-an-evaluation',
79
+ 'recipe:export-evaluation-results',
80
+ 'resource:evaluations',
81
+ ],
82
+ },
83
+ 'environment-files': {
84
+ id: 'environment-files',
85
+ title: 'Environment files',
86
+ domain: 'environments',
87
+ related: ['resource:environment-files', 'concept:problem-files', 'resource:environments'],
88
+ },
89
+ 'environment-snapshots-and-duplication': {
90
+ id: 'environment-snapshots-and-duplication',
91
+ title: 'Environment duplication',
92
+ domain: 'integrations',
93
+ related: [
94
+ 'concept:exporting-and-reusing-an-environment',
95
+ 'recipe:export-an-environment',
96
+ 'resource:environments',
97
+ ],
98
+ },
99
+ 'environment-templates-and-defaults': {
100
+ id: 'environment-templates-and-defaults',
101
+ title: 'Environment templates and defaults',
102
+ domain: 'environments',
103
+ related: ['resource:environments', 'resource:run-configs', 'resource:forms'],
104
+ },
105
+ 'evaluation-vs-problem-run': {
106
+ id: 'evaluation-vs-problem-run',
107
+ title: 'Evaluations vs. problem runs',
108
+ domain: 'evaluations',
109
+ related: ['resource:evaluations', 'resource:problem-runs', 'recipe:run-an-evaluation'],
110
+ },
111
+ 'exporting-and-reusing-an-environment': {
112
+ id: 'exporting-and-reusing-an-environment',
113
+ title: 'Exporting and reusing an environment',
114
+ domain: 'environments',
115
+ related: [
116
+ 'recipe:export-an-environment',
117
+ 'concept:environment-templates-and-defaults',
118
+ 'concept:environment-snapshots-and-duplication',
119
+ 'resource:exports',
120
+ 'resource:environments',
121
+ ],
122
+ },
123
+ 'forms-and-structured-capture': {
124
+ id: 'forms-and-structured-capture',
125
+ title: 'Forms and structured capture',
126
+ domain: 'problems',
127
+ related: ['resource:forms', 'resource:form-answers'],
128
+ },
129
+ 'grading-strategies': {
130
+ id: 'grading-strategies',
131
+ title: 'Grading strategies',
132
+ domain: 'review-qa',
133
+ related: [
134
+ 'resource:rubrics',
135
+ 'resource:problem-versions',
136
+ 'recipe:create-and-grade-a-problem',
137
+ 'recipe:grade-with-a-rubric-grader',
138
+ 'recipe:grade-with-an-agentic-grader',
139
+ 'recipe:grade-with-a-programmatic-grader',
140
+ 'recipe:grade-with-a-composite-grader',
141
+ ],
142
+ },
143
+ 'guided-tours': {
144
+ id: 'guided-tours',
145
+ title: 'Guided tours',
146
+ domain: 'authoring-aids',
147
+ related: ['recipe:set-up-a-guided-tour', 'concept:anatomy-of-a-problem-version'],
148
+ },
149
+ 'how-async-work-runs': {
150
+ id: 'how-async-work-runs',
151
+ title: 'How async work runs',
152
+ domain: 'jobs-observability',
153
+ related: [
154
+ 'recipe:run-a-job-and-read-results',
155
+ 'recipe:cancel-a-job',
156
+ 'resource:jobs',
157
+ 'resource:problem-runs',
158
+ 'concept:runs-transcripts-and-results',
159
+ ],
160
+ },
161
+ 'how-grading-works': {
162
+ id: 'how-grading-works',
163
+ title: 'How grading works',
164
+ domain: 'review-qa',
165
+ related: [
166
+ 'concept:grading-strategies',
167
+ 'concept:run-config-roles',
168
+ 'recipe:add-and-refine-a-rubric',
169
+ 'recipe:create-and-grade-a-problem',
170
+ 'resource:rubrics',
171
+ 'resource:rubric-scores',
172
+ ],
173
+ },
174
+ 'human-review-and-issues': {
175
+ id: 'human-review-and-issues',
176
+ title: 'Human review and issues',
177
+ domain: 'review-qa',
178
+ related: ['recipe:submit-and-review-a-problem', 'resource:issues', 'resource:issue-comments'],
179
+ },
180
+ 'importing-problems-and-claiming': {
181
+ id: 'importing-problems-and-claiming',
182
+ title: 'Importing problems and claiming',
183
+ domain: 'problems',
184
+ related: ['recipe:import-problems', 'resource:imports', 'resource:problems'],
185
+ },
186
+ 'interfaces-ui-cli-sdk-api': {
187
+ id: 'interfaces-ui-cli-sdk-api',
188
+ title: 'Interfaces: UI, CLI, SDK, and API',
189
+ domain: 'platform',
190
+ related: ['resource:problems', 'resource:environments'],
191
+ },
192
+ 'monitoring-and-health': {
193
+ id: 'monitoring-and-health',
194
+ title: 'Monitoring and health',
195
+ domain: 'jobs-observability',
196
+ related: ['concept:how-async-work-runs'],
197
+ },
198
+ 'organizations-and-users': {
199
+ id: 'organizations-and-users',
200
+ title: 'Organizations and users',
201
+ domain: 'administration',
202
+ related: [
203
+ 'concept:the-permission-model',
204
+ 'concept:platform-architecture',
205
+ 'concept:cost-accounting',
206
+ 'resource:environments',
207
+ ],
208
+ },
209
+ 'platform-architecture': {
210
+ id: 'platform-architecture',
211
+ title: 'Platform architecture',
212
+ domain: 'platform',
213
+ related: [
214
+ 'concept:problem-lifecycle',
215
+ 'concept:run-config-roles',
216
+ 'concept:how-async-work-runs',
217
+ 'resource:environments',
218
+ 'resource:problems',
219
+ ],
220
+ },
221
+ 'problem-files': {
222
+ id: 'problem-files',
223
+ title: 'Problem files',
224
+ domain: 'problems',
225
+ related: [
226
+ 'recipe:attach-a-file',
227
+ 'recipe:detach-and-download-a-file',
228
+ 'recipe:set-gold-standard-and-tags',
229
+ 'resource:files',
230
+ 'concept:environment-files',
231
+ ],
232
+ },
233
+ 'problem-lifecycle': {
234
+ id: 'problem-lifecycle',
235
+ title: 'The problem lifecycle',
236
+ domain: 'problems',
237
+ related: ['resource:problems', 'resource:problem-versions', 'resource:problem-runs'],
238
+ },
239
+ 'public-environments': {
240
+ id: 'public-environments',
241
+ title: 'Public environments',
242
+ domain: 'integrations',
243
+ related: ['concept:organizations-and-users', 'resource:environments'],
244
+ },
245
+ 'quality-gates-and-qa': {
246
+ id: 'quality-gates-and-qa',
247
+ title: 'Quality gates and QA',
248
+ domain: 'review-qa',
249
+ related: ['recipe:gate-a-stage-on-qa', 'resource:qa', 'resource:qa-gates'],
250
+ },
251
+ 'run-config-anatomy': {
252
+ id: 'run-config-anatomy',
253
+ title: 'Anatomy of a run config',
254
+ domain: 'run-configs',
255
+ related: [
256
+ 'concept:run-config-roles',
257
+ 'concept:verifying-with-the-probe',
258
+ 'concept:secrets-and-credentials',
259
+ 'recipe:configure-a-run-config',
260
+ 'recipe:create-a-claude-code-run-config',
261
+ 'resource:run-configs',
262
+ ],
263
+ },
264
+ 'run-config-roles': {
265
+ id: 'run-config-roles',
266
+ title: 'Run config roles and scopes',
267
+ domain: 'run-configs',
268
+ related: [
269
+ 'concept:snapshot-solvers-on-compute',
270
+ 'resource:run-configs',
271
+ 'recipe:configure-a-run-config',
272
+ 'recipe:bind-a-run-config-to-an-environment',
273
+ ],
274
+ },
275
+ 'runs-transcripts-and-results': {
276
+ id: 'runs-transcripts-and-results',
277
+ title: 'Runs, transcripts, and results',
278
+ domain: 'jobs-observability',
279
+ related: [
280
+ 'recipe:inspect-run-history-and-transcript',
281
+ 'resource:transcripts',
282
+ 'resource:problem-runs',
283
+ 'concept:how-async-work-runs',
284
+ ],
285
+ },
286
+ 'secrets-and-credentials': {
287
+ id: 'secrets-and-credentials',
288
+ title: 'Secrets and credentials',
289
+ domain: 'administration',
290
+ related: [
291
+ 'recipe:attach-a-customer-secret',
292
+ 'concept:run-config-anatomy',
293
+ 'resource:run-configs',
294
+ ],
295
+ },
296
+ 'snapshot-solvers-on-compute': {
297
+ id: 'snapshot-solvers-on-compute',
298
+ title: 'Snapshot solvers and compute runs',
299
+ domain: 'run-configs',
300
+ related: [
301
+ 'concept:run-config-roles',
302
+ 'concept:computes',
303
+ 'concept:grading-strategies',
304
+ 'resource:run-configs',
305
+ 'recipe:create-and-grade-a-problem',
306
+ 'recipe:run-a-job-and-read-results',
307
+ ],
308
+ },
309
+ tags: {
310
+ id: 'tags',
311
+ title: 'Tags',
312
+ domain: 'problems',
313
+ related: ['recipe:set-gold-standard-and-tags', 'resource:problems'],
314
+ },
315
+ 'the-cost-explorer': {
316
+ id: 'the-cost-explorer',
317
+ title: 'The cost explorer',
318
+ domain: 'cost',
319
+ related: ['concept:cost-accounting', 'resource:cost-limits'],
320
+ },
321
+ 'the-permission-model': {
322
+ id: 'the-permission-model',
323
+ title: 'The permission model',
324
+ domain: 'administration',
325
+ related: ['concept:organizations-and-users', 'concept:authentication-and-access'],
326
+ },
327
+ 'the-synthesizer': {
328
+ id: 'the-synthesizer',
329
+ title: 'The synthesizer',
330
+ domain: 'synthesizer',
331
+ related: [
332
+ 'resource:synthesizer',
333
+ 'recipe:improve-a-problem-with-the-synthesizer',
334
+ 'recipe:cancel-a-synthesizer-run',
335
+ 'concept:run-config-roles',
336
+ ],
337
+ },
338
+ 'the-taiga-integration': {
339
+ id: 'the-taiga-integration',
340
+ title: 'The Taiga integration',
341
+ domain: 'integrations',
342
+ related: ['resource:environments', 'resource:jobs'],
343
+ },
344
+ 'verifying-with-the-probe': {
345
+ id: 'verifying-with-the-probe',
346
+ title: 'Verifying a run config with the probe',
347
+ domain: 'run-configs',
348
+ related: ['concept:run-config-roles', 'concept:run-config-anatomy', 'resource:run-configs'],
349
+ },
350
+ 'worldsim-authoring': {
351
+ id: 'worldsim-authoring',
352
+ title: 'Worldsim authoring',
353
+ domain: 'authoring-aids',
354
+ related: ['concept:run-config-anatomy'],
355
+ },
356
+ };
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ /** The leading `---`…`---` YAML block of a concept page. */
3
+ export declare const ConceptFrontmatterSchema: z.ZodObject<{
4
+ title: z.ZodString;
5
+ domain: z.ZodString;
6
+ related: z.ZodDefault<z.ZodArray<z.ZodString>>;
7
+ }, z.core.$strict>;
8
+ export type ConceptFrontmatter = z.infer<typeof ConceptFrontmatterSchema>;
9
+ /** One concept in the generated reference, keyed by id (= the markdown filename stem). */
10
+ export declare const ConceptReferenceEntrySchema: z.ZodObject<{
11
+ id: z.ZodString;
12
+ title: z.ZodString;
13
+ domain: z.ZodString;
14
+ related: z.ZodArray<z.ZodString>;
15
+ }, z.core.$strict>;
16
+ export type ConceptReferenceEntry = z.infer<typeof ConceptReferenceEntrySchema>;
@@ -0,0 +1,39 @@
1
+ import { z } from 'zod';
2
+ // Types for **concept pages** — the cross-cutting Explanation quadrant of the
3
+ // docs. A concept explains an idea that spans more than one resource (e.g. the
4
+ // problem lifecycle, how grading fits together), as opposed to a per-noun resource
5
+ // intro (which stays spec-embedded). Each is authored as a frontmatter markdown
6
+ // file under `frontend/public/docs/concepts/<id>.md`; `yarn dx concepts:generate`
7
+ // reads the frontmatter into `CONCEPT_REFERENCE` (the nav index). The prose is the
8
+ // single source — the frontend fetches the `.md` directly to render the body.
9
+ //
10
+ // Two layers (mirrors recipes-schema):
11
+ // 1. Authoring frontmatter (`ConceptFrontmatter`) — what an author writes.
12
+ // 2. The generated reference entry (`ConceptReferenceEntry`) — what the
13
+ // generator emits and the frontend nav + P2 search index consume.
14
+ /** The leading `---`…`---` YAML block of a concept page. */
15
+ export const ConceptFrontmatterSchema = z
16
+ .object({
17
+ // Sentence-case nav + page title.
18
+ title: z.string().min(1),
19
+ // Canonical product domain (a `DomainId`) grouping the page in the Explanation
20
+ // nav. Kept a plain string here; membership in `DOMAINS` is enforced fail-fast
21
+ // by `concepts:generate` (this schema is loaded as source at codegen time, so
22
+ // it can only import npm deps — not the domains module).
23
+ domain: z.string().min(1),
24
+ // Slugs of related docs entries (resource hubs, recipes, other concepts).
25
+ // Collected + referential-integrity-checked by `dx docs:check` now; it will
26
+ // surface as a "Related" section in the P2 discovery layer (not yet rendered).
27
+ related: z.array(z.string()).default([]),
28
+ })
29
+ .strict();
30
+ /** One concept in the generated reference, keyed by id (= the markdown filename stem). */
31
+ export const ConceptReferenceEntrySchema = z
32
+ .object({
33
+ // Stable id = the `.md` filename stem; the docs nav slug is `concept:<id>`.
34
+ id: z.string(),
35
+ title: z.string(),
36
+ domain: z.string(),
37
+ related: z.array(z.string()),
38
+ })
39
+ .strict();
@@ -0,0 +1,15 @@
1
+ import type { DomainId } from './domains.js';
2
+ export type RelatedReference = `concept:${string}` | `recipe:${string}` | `resource:${string}` | `tutorial:${string}`;
3
+ /** Typed metadata for one Explanation page. Markdown supplies optional prose only. */
4
+ export interface ConceptReferenceEntry {
5
+ readonly id: string;
6
+ readonly title: string;
7
+ readonly domain: DomainId;
8
+ readonly related: readonly RelatedReference[];
9
+ }
10
+ /**
11
+ * Authoritative concept registry. A concept exists because it is declared here;
12
+ * an optional `apps/recursion/web/public/docs/concepts/<id>.md` file enriches its rendered
13
+ * body and search text but never controls membership or metadata.
14
+ */
15
+ export declare const CONCEPT_REFERENCE: Readonly<Record<string, ConceptReferenceEntry>>;