@lingara/api 0.0.0-reserved.0 → 0.1.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1000 @@
1
+ declare const INSPECT: unique symbol;
2
+ /** The base of every error this library raises. */
3
+ declare class LingaraError extends Error {
4
+ static [Symbol.hasInstance](value: unknown): boolean;
5
+ constructor(message: string, options?: {
6
+ cause?: unknown;
7
+ });
8
+ /** The fields a caller reads, for `JSON.stringify` and inspection. */
9
+ toJSON(): Record<string, unknown>;
10
+ [INSPECT](): string;
11
+ protected fields(): Record<string, unknown>;
12
+ }
13
+ interface ApiErrorInit {
14
+ status: number;
15
+ code: string;
16
+ message: string;
17
+ retryAfter?: number | undefined;
18
+ planId?: string | undefined;
19
+ servedVersion?: string | undefined;
20
+ }
21
+ /** A `/v1` refusal, or a stream's `error` event (then `status` is 200). */
22
+ declare class ApiError extends LingaraError {
23
+ static [Symbol.hasInstance](value: unknown): boolean;
24
+ readonly status: number;
25
+ readonly code: string;
26
+ readonly retryAfter?: number;
27
+ readonly planId?: string;
28
+ readonly servedVersion?: string;
29
+ constructor(init: ApiErrorInit);
30
+ protected fields(): Record<string, unknown>;
31
+ }
32
+ interface OAuthErrorInit {
33
+ status: number;
34
+ error: string;
35
+ description?: string | undefined;
36
+ retryAfter?: number | undefined;
37
+ }
38
+ /** A token-endpoint refusal (RFC 6749 §5.2, or `http_<status>`). */
39
+ declare class OAuthError extends LingaraError {
40
+ static [Symbol.hasInstance](value: unknown): boolean;
41
+ readonly status: number;
42
+ readonly error: string;
43
+ readonly description?: string;
44
+ readonly retryAfter?: number;
45
+ constructor(init: OAuthErrorInit);
46
+ protected fields(): Record<string, unknown>;
47
+ }
48
+ /** A 503 whose body is not JSON: the service is in maintenance. */
49
+ declare class MaintenanceError extends LingaraError {
50
+ static [Symbol.hasInstance](value: unknown): boolean;
51
+ /** The response text, at most 1 KiB. */
52
+ readonly body: string;
53
+ readonly retryAfter?: number;
54
+ constructor(body: string, retryAfter?: number);
55
+ protected fields(): Record<string, unknown>;
56
+ }
57
+ type TransportKind = "connect" | "tls" | "reset" | "timeout" | "stream_ended_early" | "malformed_response" | "malformed_event";
58
+ /** No usable HTTP answer. `cause` is the runtime's error, redacted. */
59
+ declare class TransportError extends LingaraError {
60
+ static [Symbol.hasInstance](value: unknown): boolean;
61
+ readonly kind: TransportKind;
62
+ constructor(kind: TransportKind, cause?: unknown);
63
+ protected fields(): Record<string, unknown>;
64
+ }
65
+
66
+ interface components {
67
+ schemas: {
68
+ VocabRequest: {
69
+ /** Format: uint8 */
70
+ level: number;
71
+ source_lang: string;
72
+ target_lang: string;
73
+ /** Format: uint8 */
74
+ count?: number | null;
75
+ };
76
+ LessonPlanCreateRequest: {
77
+ context: string;
78
+ source_lang: string;
79
+ target_lang: string;
80
+ /** Format: uint8 */
81
+ level: number;
82
+ };
83
+ TutorTurnRequest: {
84
+ message: string;
85
+ /** @default [] */
86
+ history: components["schemas"]["TurnEntry"][];
87
+ source_lang: string;
88
+ target_lang: string;
89
+ /** Format: uint8 */
90
+ level?: number | null;
91
+ character?: string | null;
92
+ situation?: string | null;
93
+ };
94
+ TurnEntry: {
95
+ role: components["schemas"]["TurnRole"];
96
+ content: string;
97
+ };
98
+ /** @enum {string} */
99
+ TurnRole: "user" | "assistant";
100
+ VocabStarted: {
101
+ meta: components["schemas"]["VocabMeta"];
102
+ };
103
+ VocabMeta: {
104
+ /** Format: uint8 */
105
+ level: number;
106
+ source_lang: string;
107
+ target_lang: string;
108
+ framework: string;
109
+ /** Format: uint32 */
110
+ count: number;
111
+ ai_generated: boolean;
112
+ };
113
+ VocabItem: {
114
+ word: string;
115
+ pronunciation?: string | null;
116
+ reading?: string | null;
117
+ translation: string;
118
+ example?: components["schemas"]["VocabExample"] | null;
119
+ image_url?: string | null;
120
+ };
121
+ VocabExample: {
122
+ sentence: string;
123
+ translation: string;
124
+ };
125
+ LessonPlan: {
126
+ /** Format: uuid */
127
+ id: string;
128
+ status: components["schemas"]["PlanStatus"];
129
+ title?: string | null;
130
+ source_lang: string;
131
+ target_lang: string;
132
+ /** Format: uint8 */
133
+ level: number;
134
+ /** Format: date-time */
135
+ created_at: string;
136
+ /** Format: date-time */
137
+ completed_at?: string | null;
138
+ ai_generated: boolean;
139
+ content?: components["schemas"]["LessonPlanContent"] | null;
140
+ };
141
+ /** @enum {string} */
142
+ PlanStatus: "generating" | "partial" | "complete";
143
+ LessonPlanContent: {
144
+ introduction?: string | null;
145
+ learning_objectives: string[];
146
+ vocabulary: components["schemas"]["PlanWord"][];
147
+ sets: components["schemas"]["PlanSet"][];
148
+ };
149
+ PlanWord: {
150
+ word: string;
151
+ pronunciation?: string | null;
152
+ translation: string;
153
+ };
154
+ PlanSet: {
155
+ /** Format: uint8 */
156
+ number: number;
157
+ context?: string | null;
158
+ questions: components["schemas"]["PlanQuestion"][];
159
+ };
160
+ PlanQuestion: {
161
+ type: string;
162
+ prompt: string;
163
+ options?: string[] | null;
164
+ answer: string;
165
+ explanation: string;
166
+ hint?: string | null;
167
+ };
168
+ PlanStarted: {
169
+ /** Format: uuid */
170
+ plan_id: string;
171
+ };
172
+ PlanPhase: {
173
+ phase: string;
174
+ /** Format: uint8 */
175
+ attempt: number;
176
+ };
177
+ PlanResult: {
178
+ plan: components["schemas"]["LessonPlan"];
179
+ };
180
+ PlanPending: {
181
+ /** Format: uuid */
182
+ plan_id: string;
183
+ status: components["schemas"]["PlanStatus"];
184
+ };
185
+ TurnDelta: {
186
+ text: string;
187
+ };
188
+ Usage: {
189
+ allowance: components["schemas"]["AllowanceRow"][];
190
+ /** @description This client's calls and units since midnight UTC on the first of the month. Present only for a metered client, whose calls spend no allowance. It can trail your latest call by up to five seconds. */
191
+ ledger?: components["schemas"]["UsageLedger"] | null;
192
+ };
193
+ UsageLedger: {
194
+ /** Format: date-time */
195
+ since: string;
196
+ /** Format: uint64 */
197
+ calls: number;
198
+ /** Format: uint64 */
199
+ units: number;
200
+ };
201
+ AllowanceRow: {
202
+ feature: string;
203
+ window: string;
204
+ /** Format: uint32 */
205
+ limit: number;
206
+ /** Format: uint32 */
207
+ used: number;
208
+ /** Format: uint32 */
209
+ remaining: number;
210
+ /** Format: int64 */
211
+ reset_at?: number | null;
212
+ };
213
+ VersionList: {
214
+ current: string | null;
215
+ development: string | null;
216
+ versions: components["schemas"]["VersionSummary"][];
217
+ };
218
+ VersionSummary: {
219
+ id: string;
220
+ state: components["schemas"]["VersionState"];
221
+ lts: boolean;
222
+ /** Format: date-time */
223
+ minted_at: string;
224
+ /** Format: date-time */
225
+ sunset_at: string | null;
226
+ };
227
+ VersionDetail: {
228
+ id: string;
229
+ state: components["schemas"]["VersionState"];
230
+ lts: boolean;
231
+ /** Format: date-time */
232
+ minted_at: string;
233
+ /** Format: date-time */
234
+ sunset_at: string | null;
235
+ summary: string | null;
236
+ history: components["schemas"]["VersionHistoryEntry"][];
237
+ spec: components["schemas"]["VersionSpec"];
238
+ };
239
+ /** @enum {string} */
240
+ VersionState: "development" | "supported" | "lts" | "deprecated" | "discontinued";
241
+ VersionHistoryEntry: {
242
+ state: components["schemas"]["VersionState"];
243
+ /** Format: date-time */
244
+ at: string;
245
+ };
246
+ VersionSpec: {
247
+ url: string;
248
+ sha256: string | null;
249
+ };
250
+ Error: {
251
+ /** @description Why the request was refused, as a stable code to branch on: for example `insufficient_scope` (`403`), `rate_limited` (`429`) and, for a metered client, `spend_cap_reached` (`402`) and `metered_billing_inactive` (`402`). */
252
+ code: string;
253
+ error: string;
254
+ };
255
+ Notice: {
256
+ code: string;
257
+ message: string;
258
+ };
259
+ StreamError: {
260
+ code: string;
261
+ message: string;
262
+ /** Format: uuid */
263
+ plan_id?: string | null;
264
+ };
265
+ Done: Record<string, never>;
266
+ GenerateVocabularyEventStarted: {
267
+ /**
268
+ * @description discriminator enum property added by openapi-typescript
269
+ * @enum {string}
270
+ */
271
+ event: "started";
272
+ data: components["schemas"]["VocabStarted"];
273
+ };
274
+ GenerateVocabularyEventItem: {
275
+ /**
276
+ * @description discriminator enum property added by openapi-typescript
277
+ * @enum {string}
278
+ */
279
+ event: "item";
280
+ data: components["schemas"]["VocabItem"];
281
+ };
282
+ GenerateVocabularyEventDone: {
283
+ /**
284
+ * @description discriminator enum property added by openapi-typescript
285
+ * @enum {string}
286
+ */
287
+ event: "done";
288
+ data: components["schemas"]["Done"];
289
+ };
290
+ GenerateVocabularyEventError: {
291
+ /**
292
+ * @description discriminator enum property added by openapi-typescript
293
+ * @enum {string}
294
+ */
295
+ event: "error";
296
+ data: components["schemas"]["StreamError"];
297
+ };
298
+ GenerateVocabularyEvent: components["schemas"]["GenerateVocabularyEventStarted"] | components["schemas"]["GenerateVocabularyEventItem"] | components["schemas"]["GenerateVocabularyEventDone"] | components["schemas"]["GenerateVocabularyEventError"];
299
+ CreateLessonPlanEventStarted: {
300
+ /**
301
+ * @description discriminator enum property added by openapi-typescript
302
+ * @enum {string}
303
+ */
304
+ event: "started";
305
+ data: components["schemas"]["PlanStarted"];
306
+ };
307
+ CreateLessonPlanEventPhase: {
308
+ /**
309
+ * @description discriminator enum property added by openapi-typescript
310
+ * @enum {string}
311
+ */
312
+ event: "phase";
313
+ data: components["schemas"]["PlanPhase"];
314
+ };
315
+ CreateLessonPlanEventResult: {
316
+ /**
317
+ * @description discriminator enum property added by openapi-typescript
318
+ * @enum {string}
319
+ */
320
+ event: "result";
321
+ data: components["schemas"]["PlanResult"];
322
+ };
323
+ CreateLessonPlanEventError: {
324
+ /**
325
+ * @description discriminator enum property added by openapi-typescript
326
+ * @enum {string}
327
+ */
328
+ event: "error";
329
+ data: components["schemas"]["StreamError"];
330
+ };
331
+ CreateLessonPlanEvent: components["schemas"]["CreateLessonPlanEventStarted"] | components["schemas"]["CreateLessonPlanEventPhase"] | components["schemas"]["CreateLessonPlanEventResult"] | components["schemas"]["CreateLessonPlanEventError"];
332
+ StreamLessonPlanEventStarted: {
333
+ /**
334
+ * @description discriminator enum property added by openapi-typescript
335
+ * @enum {string}
336
+ */
337
+ event: "started";
338
+ data: components["schemas"]["PlanStarted"];
339
+ };
340
+ StreamLessonPlanEventPhase: {
341
+ /**
342
+ * @description discriminator enum property added by openapi-typescript
343
+ * @enum {string}
344
+ */
345
+ event: "phase";
346
+ data: components["schemas"]["PlanPhase"];
347
+ };
348
+ StreamLessonPlanEventResult: {
349
+ /**
350
+ * @description discriminator enum property added by openapi-typescript
351
+ * @enum {string}
352
+ */
353
+ event: "result";
354
+ data: components["schemas"]["PlanResult"];
355
+ };
356
+ StreamLessonPlanEventPending: {
357
+ /**
358
+ * @description discriminator enum property added by openapi-typescript
359
+ * @enum {string}
360
+ */
361
+ event: "pending";
362
+ data: components["schemas"]["PlanPending"];
363
+ };
364
+ StreamLessonPlanEventError: {
365
+ /**
366
+ * @description discriminator enum property added by openapi-typescript
367
+ * @enum {string}
368
+ */
369
+ event: "error";
370
+ data: components["schemas"]["StreamError"];
371
+ };
372
+ StreamLessonPlanEvent: components["schemas"]["StreamLessonPlanEventStarted"] | components["schemas"]["StreamLessonPlanEventPhase"] | components["schemas"]["StreamLessonPlanEventResult"] | components["schemas"]["StreamLessonPlanEventPending"] | components["schemas"]["StreamLessonPlanEventError"];
373
+ SendTutorMessageEventDelta: {
374
+ /**
375
+ * @description discriminator enum property added by openapi-typescript
376
+ * @enum {string}
377
+ */
378
+ event: "delta";
379
+ data: components["schemas"]["TurnDelta"];
380
+ };
381
+ SendTutorMessageEventNotice: {
382
+ /**
383
+ * @description discriminator enum property added by openapi-typescript
384
+ * @enum {string}
385
+ */
386
+ event: "notice";
387
+ data: components["schemas"]["Notice"];
388
+ };
389
+ SendTutorMessageEventDone: {
390
+ /**
391
+ * @description discriminator enum property added by openapi-typescript
392
+ * @enum {string}
393
+ */
394
+ event: "done";
395
+ data: components["schemas"]["Done"];
396
+ };
397
+ SendTutorMessageEventError: {
398
+ /**
399
+ * @description discriminator enum property added by openapi-typescript
400
+ * @enum {string}
401
+ */
402
+ event: "error";
403
+ data: components["schemas"]["StreamError"];
404
+ };
405
+ SendTutorMessageEvent: components["schemas"]["SendTutorMessageEventDelta"] | components["schemas"]["SendTutorMessageEventNotice"] | components["schemas"]["SendTutorMessageEventDone"] | components["schemas"]["SendTutorMessageEventError"];
406
+ };
407
+ responses: {
408
+ /** @description The request was refused. `code` says why, and `error` says it in words. */
409
+ Error: {
410
+ headers: {
411
+ [name: string]: unknown;
412
+ };
413
+ content: {
414
+ "application/json": components["schemas"]["Error"];
415
+ };
416
+ };
417
+ /** @description A metered client's call was refused before it spent anything. `spend_cap_reached`: the client or its account has reached its monthly spending limit; raise the limit on the Integrations page. `metered_billing_inactive`: usage billing is not active for this account; set it up, or update the payment method, on the Integrations page. */
418
+ PaymentRequired: {
419
+ headers: {
420
+ [name: string]: unknown;
421
+ };
422
+ content: {
423
+ "application/json": components["schemas"]["Error"];
424
+ };
425
+ };
426
+ /** @description The API version this request is answered under has been discontinued. Send a supported version in `Lingara-Version`, or re-pin the client. */
427
+ VersionDiscontinued: {
428
+ headers: {
429
+ [name: string]: unknown;
430
+ };
431
+ content: {
432
+ "application/json": components["schemas"]["Error"];
433
+ };
434
+ };
435
+ /** @description The service is temporarily unavailable; retry after the number of seconds in `Retry-After`. During maintenance the body is plain text rather than the error envelope. */
436
+ Unavailable: {
437
+ headers: {
438
+ [name: string]: unknown;
439
+ };
440
+ content: {
441
+ "application/json": components["schemas"]["Error"];
442
+ "text/plain": string;
443
+ };
444
+ };
445
+ };
446
+ parameters: {
447
+ PlanId: string;
448
+ VersionId: string;
449
+ /** @description The API version to answer this request under. Without it, an access token gets the version its client is pinned to, and a request with no token gets the current version. The version still in development is reached only by naming it here. An unknown version answers `400` with code `api_version_unknown`. `GET /v1/versions` lists the versions. */
450
+ LingaraVersion: string;
451
+ };
452
+ requestBodies: never;
453
+ headers: {
454
+ /** @description The API version this response was answered under. Absent until the first version is frozen. */
455
+ LingaraVersion: string;
456
+ /** @description When this response's API version was deprecated, as `@` followed by Unix seconds. Present only on a deprecated version. */
457
+ Deprecation: string;
458
+ /** @description The date from which this response's API version may be discontinued. Present only on a deprecated version. */
459
+ Sunset: string;
460
+ /** @description A link, with relation `deprecation`, to this API version's details. Present only on a deprecated version. */
461
+ Link: string;
462
+ };
463
+ pathItems: never;
464
+ }
465
+ interface operations {
466
+ getLessonPlan: {
467
+ parameters: {
468
+ query?: never;
469
+ header?: {
470
+ /** @description The API version to answer this request under. Without it, an access token gets the version its client is pinned to, and a request with no token gets the current version. The version still in development is reached only by naming it here. An unknown version answers `400` with code `api_version_unknown`. `GET /v1/versions` lists the versions. */
471
+ "Lingara-Version"?: components["parameters"]["LingaraVersion"];
472
+ };
473
+ path: {
474
+ id: components["parameters"]["PlanId"];
475
+ };
476
+ cookie?: never;
477
+ };
478
+ requestBody?: never;
479
+ responses: {
480
+ /** @description The lesson plan */
481
+ 200: {
482
+ headers: {
483
+ "Lingara-Version": components["headers"]["LingaraVersion"];
484
+ Deprecation: components["headers"]["Deprecation"];
485
+ Sunset: components["headers"]["Sunset"];
486
+ Link: components["headers"]["Link"];
487
+ [name: string]: unknown;
488
+ };
489
+ content: {
490
+ /**
491
+ * @example {
492
+ * "id": "3f1c2a9e-5b7d-4e21-9a0c-6d8e4f2b1a37",
493
+ * "status": "complete",
494
+ * "title": "At the night market",
495
+ * "source_lang": "en",
496
+ * "target_lang": "zh",
497
+ * "level": 2,
498
+ * "created_at": "2026-09-23T10:00:00Z",
499
+ * "completed_at": "2026-09-23T10:00:41Z",
500
+ * "ai_generated": true,
501
+ * "content": {
502
+ * "introduction": "Order food and ask prices at a night market.",
503
+ * "learning_objectives": [
504
+ * "Ask how much something costs"
505
+ * ],
506
+ * "vocabulary": [
507
+ * {
508
+ * "word": "多少钱",
509
+ * "pronunciation": "duōshao qián",
510
+ * "translation": "how much"
511
+ * }
512
+ * ],
513
+ * "sets": [
514
+ * {
515
+ * "number": 1,
516
+ * "questions": [
517
+ * {
518
+ * "type": "multiple_choice_word",
519
+ * "prompt": "Which word asks for a price?",
520
+ * "options": [
521
+ * "多少钱",
522
+ * "谢谢"
523
+ * ],
524
+ * "answer": "多少钱",
525
+ * "explanation": "多少钱 means how much money."
526
+ * }
527
+ * ]
528
+ * }
529
+ * ]
530
+ * }
531
+ * }
532
+ */
533
+ "application/json": components["schemas"]["LessonPlan"];
534
+ };
535
+ };
536
+ 410: components["responses"]["VersionDiscontinued"];
537
+ 503: components["responses"]["Unavailable"];
538
+ "4XX": components["responses"]["Error"];
539
+ "5XX": components["responses"]["Error"];
540
+ };
541
+ };
542
+ getUsage: {
543
+ parameters: {
544
+ query?: never;
545
+ header?: {
546
+ /** @description The API version to answer this request under. Without it, an access token gets the version its client is pinned to, and a request with no token gets the current version. The version still in development is reached only by naming it here. An unknown version answers `400` with code `api_version_unknown`. `GET /v1/versions` lists the versions. */
547
+ "Lingara-Version"?: components["parameters"]["LingaraVersion"];
548
+ };
549
+ path?: never;
550
+ cookie?: never;
551
+ };
552
+ requestBody?: never;
553
+ responses: {
554
+ /** @description Your allowance */
555
+ 200: {
556
+ headers: {
557
+ "Lingara-Version": components["headers"]["LingaraVersion"];
558
+ Deprecation: components["headers"]["Deprecation"];
559
+ Sunset: components["headers"]["Sunset"];
560
+ Link: components["headers"]["Link"];
561
+ [name: string]: unknown;
562
+ };
563
+ content: {
564
+ /**
565
+ * @example {
566
+ * "allowance": [
567
+ * {
568
+ * "feature": "vocab",
569
+ * "window": "daily",
570
+ * "limit": 50,
571
+ * "used": 12,
572
+ * "remaining": 38,
573
+ * "reset_at": 1790208000
574
+ * },
575
+ * {
576
+ * "feature": "lesson_plans",
577
+ * "window": "lifetime",
578
+ * "limit": 3,
579
+ * "used": 1,
580
+ * "remaining": 2
581
+ * }
582
+ * ]
583
+ * }
584
+ */
585
+ "application/json": components["schemas"]["Usage"];
586
+ };
587
+ };
588
+ 410: components["responses"]["VersionDiscontinued"];
589
+ 503: components["responses"]["Unavailable"];
590
+ "4XX": components["responses"]["Error"];
591
+ "5XX": components["responses"]["Error"];
592
+ };
593
+ };
594
+ getOpenApiDocument: {
595
+ parameters: {
596
+ query?: never;
597
+ header?: {
598
+ /** @description The API version to answer this request under. Without it, an access token gets the version its client is pinned to, and a request with no token gets the current version. The version still in development is reached only by naming it here. An unknown version answers `400` with code `api_version_unknown`. `GET /v1/versions` lists the versions. */
599
+ "Lingara-Version"?: components["parameters"]["LingaraVersion"];
600
+ };
601
+ path?: never;
602
+ cookie?: never;
603
+ };
604
+ requestBody?: never;
605
+ responses: {
606
+ /** @description The OpenAPI document */
607
+ 200: {
608
+ headers: {
609
+ "Lingara-Version": components["headers"]["LingaraVersion"];
610
+ Deprecation: components["headers"]["Deprecation"];
611
+ Sunset: components["headers"]["Sunset"];
612
+ Link: components["headers"]["Link"];
613
+ [name: string]: unknown;
614
+ };
615
+ content: {
616
+ "application/json": Record<string, never>;
617
+ };
618
+ };
619
+ 410: components["responses"]["VersionDiscontinued"];
620
+ 503: components["responses"]["Unavailable"];
621
+ "4XX": components["responses"]["Error"];
622
+ };
623
+ };
624
+ listApiVersions: {
625
+ parameters: {
626
+ query?: never;
627
+ header?: {
628
+ /** @description The API version to answer this request under. Without it, an access token gets the version its client is pinned to, and a request with no token gets the current version. The version still in development is reached only by naming it here. An unknown version answers `400` with code `api_version_unknown`. `GET /v1/versions` lists the versions. */
629
+ "Lingara-Version"?: components["parameters"]["LingaraVersion"];
630
+ };
631
+ path?: never;
632
+ cookie?: never;
633
+ };
634
+ requestBody?: never;
635
+ responses: {
636
+ /** @description Every API version */
637
+ 200: {
638
+ headers: {
639
+ "Lingara-Version": components["headers"]["LingaraVersion"];
640
+ Deprecation: components["headers"]["Deprecation"];
641
+ Sunset: components["headers"]["Sunset"];
642
+ Link: components["headers"]["Link"];
643
+ [name: string]: unknown;
644
+ };
645
+ content: {
646
+ /**
647
+ * @example {
648
+ * "current": "2026-10-brave-otter",
649
+ * "development": "2026-11-quiet-lantern",
650
+ * "versions": [
651
+ * {
652
+ * "id": "2026-10-gentle-heron",
653
+ * "state": "deprecated",
654
+ * "lts": true,
655
+ * "minted_at": "2026-10-01T09:00:00Z",
656
+ * "sunset_at": "2027-03-01T00:00:00Z"
657
+ * },
658
+ * {
659
+ * "id": "2026-10-brave-otter",
660
+ * "state": "supported",
661
+ * "lts": false,
662
+ * "minted_at": "2026-10-01T09:00:05Z",
663
+ * "sunset_at": null
664
+ * },
665
+ * {
666
+ * "id": "2026-11-quiet-lantern",
667
+ * "state": "development",
668
+ * "lts": false,
669
+ * "minted_at": "2026-11-02T10:00:00Z",
670
+ * "sunset_at": null
671
+ * }
672
+ * ]
673
+ * }
674
+ */
675
+ "application/json": components["schemas"]["VersionList"];
676
+ };
677
+ };
678
+ 410: components["responses"]["VersionDiscontinued"];
679
+ 503: components["responses"]["Unavailable"];
680
+ "4XX": components["responses"]["Error"];
681
+ "5XX": components["responses"]["Error"];
682
+ };
683
+ };
684
+ getApiVersion: {
685
+ parameters: {
686
+ query?: never;
687
+ header?: {
688
+ /** @description The API version to answer this request under. Without it, an access token gets the version its client is pinned to, and a request with no token gets the current version. The version still in development is reached only by naming it here. An unknown version answers `400` with code `api_version_unknown`. `GET /v1/versions` lists the versions. */
689
+ "Lingara-Version"?: components["parameters"]["LingaraVersion"];
690
+ };
691
+ path: {
692
+ id: components["parameters"]["VersionId"];
693
+ };
694
+ cookie?: never;
695
+ };
696
+ requestBody?: never;
697
+ responses: {
698
+ /** @description The API version */
699
+ 200: {
700
+ headers: {
701
+ "Lingara-Version": components["headers"]["LingaraVersion"];
702
+ Deprecation: components["headers"]["Deprecation"];
703
+ Sunset: components["headers"]["Sunset"];
704
+ Link: components["headers"]["Link"];
705
+ [name: string]: unknown;
706
+ };
707
+ content: {
708
+ /**
709
+ * @example {
710
+ * "id": "2026-10-brave-otter",
711
+ * "state": "supported",
712
+ * "lts": false,
713
+ * "minted_at": "2026-10-01T09:00:05Z",
714
+ * "sunset_at": null,
715
+ * "summary": "The first surface.",
716
+ * "history": [
717
+ * {
718
+ * "state": "development",
719
+ * "at": "2026-10-01T09:00:05Z"
720
+ * },
721
+ * {
722
+ * "state": "supported",
723
+ * "at": "2026-11-02T10:00:00Z"
724
+ * }
725
+ * ],
726
+ * "spec": {
727
+ * "url": "/v1/openapi.json",
728
+ * "sha256": "3b7e0c1f9a2d4e5b6c7d8e9f0a1b2c3d4e5f60718293a4b5c6d7e8f9a0b1c2d3"
729
+ * }
730
+ * }
731
+ */
732
+ "application/json": components["schemas"]["VersionDetail"];
733
+ };
734
+ };
735
+ 410: components["responses"]["VersionDiscontinued"];
736
+ 503: components["responses"]["Unavailable"];
737
+ "4XX": components["responses"]["Error"];
738
+ "5XX": components["responses"]["Error"];
739
+ };
740
+ };
741
+ }
742
+
743
+ type Schemas = components["schemas"];
744
+ type VocabRequest = Schemas["VocabRequest"];
745
+ type LessonPlanCreateRequest = Schemas["LessonPlanCreateRequest"];
746
+ type TutorTurnRequest = Schemas["TutorTurnRequest"];
747
+ type GenerateVocabularyEvent = Schemas["GenerateVocabularyEvent"];
748
+ type CreateLessonPlanEvent = Schemas["CreateLessonPlanEvent"];
749
+ type StreamLessonPlanEvent = Schemas["StreamLessonPlanEvent"];
750
+ type SendTutorMessageEvent = Schemas["SendTutorMessageEvent"];
751
+ type VocabStarted = Schemas["VocabStarted"];
752
+ type VocabItem = Schemas["VocabItem"];
753
+ type VocabMeta = Schemas["VocabMeta"];
754
+ type VocabExample = Schemas["VocabExample"];
755
+ type PlanStarted = Schemas["PlanStarted"];
756
+ type PlanPhase = Schemas["PlanPhase"];
757
+ type PlanResult = Schemas["PlanResult"];
758
+ type PlanPending = Schemas["PlanPending"];
759
+ type TurnDelta = Schemas["TurnDelta"];
760
+ type Notice = Schemas["Notice"];
761
+ type StreamError = Schemas["StreamError"];
762
+ type LessonPlan = Schemas["LessonPlan"];
763
+ type LessonPlanContent = Schemas["LessonPlanContent"];
764
+ type PlanStatus = Schemas["PlanStatus"];
765
+ type Usage = Schemas["Usage"];
766
+ type AllowanceRow = Schemas["AllowanceRow"];
767
+ type VersionList = Schemas["VersionList"];
768
+ type VersionDetail = Schemas["VersionDetail"];
769
+ type VersionSummary = Schemas["VersionSummary"];
770
+ type VersionState = Schemas["VersionState"];
771
+
772
+ /** Wall-clock time, in epoch milliseconds. A testing seam. */
773
+ interface Clock {
774
+ now(): number;
775
+ }
776
+ /**
777
+ * Waits `ms` milliseconds, or rejects with `signal.reason` as soon as the
778
+ * signal aborts. A testing seam.
779
+ */
780
+ type Sleeper = (ms: number, signal?: AbortSignal) => Promise<void>;
781
+
782
+ declare const STREAMS: {
783
+ readonly generateVocabulary: {
784
+ readonly method: "POST";
785
+ readonly path: "/v1/vocab/stream";
786
+ readonly requestBody: "VocabRequest";
787
+ readonly union: "GenerateVocabularyEvent";
788
+ readonly events: readonly ["started", "item", "done", "error"];
789
+ readonly ends: {
790
+ readonly done: "end";
791
+ readonly error: "raise";
792
+ };
793
+ };
794
+ readonly createLessonPlan: {
795
+ readonly method: "POST";
796
+ readonly path: "/v1/lesson-plans";
797
+ readonly requestBody: "LessonPlanCreateRequest";
798
+ readonly union: "CreateLessonPlanEvent";
799
+ readonly events: readonly ["started", "phase", "result", "error"];
800
+ readonly ends: {
801
+ readonly result: "yield";
802
+ readonly error: "raise";
803
+ };
804
+ };
805
+ readonly streamLessonPlan: {
806
+ readonly method: "GET";
807
+ readonly path: "/v1/lesson-plans/{id}/stream";
808
+ readonly requestBody: null;
809
+ readonly union: "StreamLessonPlanEvent";
810
+ readonly events: readonly ["started", "phase", "result", "pending", "error"];
811
+ readonly ends: {
812
+ readonly result: "yield";
813
+ readonly pending: "yield";
814
+ readonly error: "raise";
815
+ };
816
+ };
817
+ readonly sendTutorMessage: {
818
+ readonly method: "POST";
819
+ readonly path: "/v1/tutor/message";
820
+ readonly requestBody: "TutorTurnRequest";
821
+ readonly union: "SendTutorMessageEvent";
822
+ readonly events: readonly ["delta", "notice", "done", "error"];
823
+ readonly ends: {
824
+ readonly done: "end";
825
+ readonly error: "raise";
826
+ };
827
+ };
828
+ };
829
+ type StreamOperation = keyof typeof STREAMS;
830
+
831
+ /** What a stream yields: every event but `done` and `error`. */
832
+ type Yielded<E> = Exclude<E, {
833
+ event: "done";
834
+ } | {
835
+ event: "error";
836
+ }>;
837
+ /** An opened stream: a 200 `text/event-stream` response and its echo. */
838
+ interface OpenedStream {
839
+ response: Response;
840
+ servedVersion: string | undefined;
841
+ }
842
+ interface EventStreamInit {
843
+ operation: StreamOperation;
844
+ /** Sends the request (auth, retries, error mapping) under `signal`. */
845
+ open: (signal: AbortSignal) => Promise<OpenedStream>;
846
+ signal?: AbortSignal | undefined;
847
+ idleTimeoutMs: number;
848
+ }
849
+ /** A stream of events. `for await` it; `break` or `close()` ends it. */
850
+ declare class EventStream<E extends {
851
+ event: string;
852
+ }> implements AsyncIterableIterator<Yielded<E>> {
853
+ #private;
854
+ constructor(init: EventStreamInit);
855
+ /**
856
+ * The `Lingara-Version` echo. Reading it starts the request if iteration
857
+ * has not. Never rejects: `undefined` when the request fails or the stream
858
+ * closes first.
859
+ */
860
+ get servedVersion(): Promise<string | undefined>;
861
+ [Symbol.asyncIterator](): this;
862
+ next(): Promise<IteratorResult<Yielded<E>>>;
863
+ return(): Promise<IteratorResult<Yielded<E>>>;
864
+ /** Ends the stream and closes the connection. Idempotent. */
865
+ close(): Promise<void>;
866
+ }
867
+
868
+ type FetchLike = (input: string, init: RequestInit) => Promise<Response>;
869
+
870
+ /** Where the client gets its access tokens. A caller may supply their own. */
871
+ interface TokenSource {
872
+ /** An access token. `signal` abandons this caller's wait only. */
873
+ token(options?: {
874
+ signal?: AbortSignal;
875
+ }): Promise<string>;
876
+ /** Forgets `token` only if it is still the cached one. */
877
+ invalidate(token: string): void;
878
+ }
879
+ interface ClientCredentialsOptions {
880
+ clientId: string;
881
+ clientSecret: string;
882
+ /** `"basic"` (the default) is `client_secret_basic`; `"post"` is `client_secret_post`. */
883
+ auth?: "basic" | "post" | undefined;
884
+ scopes?: readonly string[] | undefined;
885
+ tokenUrl?: string | undefined;
886
+ maxAttempts?: number | undefined;
887
+ retryAfterCapSeconds?: number | undefined;
888
+ tokenRequestTimeoutMs?: number | undefined;
889
+ userAgentSuffix?: string | undefined;
890
+ /** A testing seam. */
891
+ clock?: Clock | undefined;
892
+ /** A testing seam. */
893
+ sleeper?: Sleeper | undefined;
894
+ fetch?: FetchLike | undefined;
895
+ }
896
+ declare const DEFAULT_TOKEN_URL = "https://api.getlingara.com/oauth/token";
897
+ /** The OAuth 2.0 client-credentials grant against `/oauth/token`. */
898
+ declare class ClientCredentials implements TokenSource {
899
+ #private;
900
+ readonly clientId: string;
901
+ constructor(options: ClientCredentialsOptions);
902
+ token(options?: {
903
+ signal?: AbortSignal;
904
+ }): Promise<string>;
905
+ invalidate(token: string): void;
906
+ /** The cached access token, raw. The one accessor that does not redact. */
907
+ exposeToken(): string | undefined;
908
+ toJSON(): Record<string, unknown>;
909
+ [INSPECT](): string;
910
+ toString(): string;
911
+ }
912
+
913
+ /** What a response under a deprecated version says about it. */
914
+ interface DeprecationNotice {
915
+ /** The `Lingara-Version` echo. */
916
+ version?: string;
917
+ /** `Deprecation`, parsed from `@<unix seconds>`; absent when unparseable. */
918
+ deprecatedAt?: Date;
919
+ /** `Sunset`, parsed from an IMF-fixdate; absent when unparseable or missing. */
920
+ sunsetAt?: Date;
921
+ /** `Link`: the raw value, and its target resolved against the request URL. */
922
+ link?: {
923
+ raw: string;
924
+ url?: URL;
925
+ };
926
+ /** The raw `Deprecation` header. */
927
+ deprecation: string;
928
+ /** The raw `Sunset` header. */
929
+ sunset?: string;
930
+ }
931
+ type DeprecationHook = (notice: DeprecationNotice) => void;
932
+
933
+ interface LingaraOptions {
934
+ clientId?: string;
935
+ clientSecret?: string;
936
+ /** `"basic"` (the default) or `"post"` (`client_secret_post`). */
937
+ auth?: "basic" | "post";
938
+ scopes?: readonly string[];
939
+ /** Replaces the built-in client-credentials source. Not with `clientSecret`. */
940
+ tokenSource?: TokenSource;
941
+ baseUrl?: string;
942
+ tokenUrl?: string;
943
+ /** Pins every `/v1` request to this API version. */
944
+ version?: string;
945
+ /** Called once per response under a deprecated version. */
946
+ onDeprecation?: DeprecationHook;
947
+ /** Tries per HTTP request; `1` turns retries off. Default 3. */
948
+ maxAttempts?: number;
949
+ /** Default 60. */
950
+ retryAfterCapSeconds?: number;
951
+ /** Default 120 000. */
952
+ streamIdleTimeoutMs?: number;
953
+ /** Default 30 000. */
954
+ tokenRequestTimeoutMs?: number;
955
+ /** Appended to the `User-Agent` after one space. */
956
+ userAgentSuffix?: string;
957
+ /** A testing seam: epoch milliseconds. */
958
+ clock?: Clock;
959
+ /** A testing seam. */
960
+ sleeper?: Sleeper;
961
+ /** Defaults to `globalThis.fetch`. */
962
+ fetch?: FetchLike;
963
+ }
964
+ interface CallOptions {
965
+ signal?: AbortSignal;
966
+ }
967
+ /** A JSON result, with the `Lingara-Version` echo beside it (non-enumerable). */
968
+ type WithServedVersion<T> = T & {
969
+ readonly servedVersion?: string;
970
+ };
971
+ type JsonOk<Op extends keyof operations> = operations[Op]["responses"][200]["content"]["application/json"];
972
+ declare const DEFAULT_BASE_URL = "https://api.getlingara.com";
973
+ /** The Lingara API. Server-side only: Node, Deno and Bun. */
974
+ declare class Lingara {
975
+ #private;
976
+ readonly clientId: string | undefined;
977
+ constructor(options?: LingaraOptions);
978
+ /** The token source in use, if the client has credentials. */
979
+ get tokenSource(): TokenSource | undefined;
980
+ generateVocabulary(body: VocabRequest, options?: CallOptions): EventStream<GenerateVocabularyEvent>;
981
+ createLessonPlan(body: LessonPlanCreateRequest, options?: CallOptions): EventStream<CreateLessonPlanEvent>;
982
+ streamLessonPlan(params: {
983
+ id: string;
984
+ }, options?: CallOptions): EventStream<StreamLessonPlanEvent>;
985
+ sendTutorMessage(body: TutorTurnRequest, options?: CallOptions): EventStream<SendTutorMessageEvent>;
986
+ getLessonPlan(params: {
987
+ id: string;
988
+ }, options?: CallOptions): Promise<WithServedVersion<JsonOk<"getLessonPlan">>>;
989
+ getUsage(options?: CallOptions): Promise<WithServedVersion<JsonOk<"getUsage">>>;
990
+ getOpenApiDocument(options?: CallOptions): Promise<WithServedVersion<JsonOk<"getOpenApiDocument">>>;
991
+ listApiVersions(options?: CallOptions): Promise<WithServedVersion<JsonOk<"listApiVersions">>>;
992
+ getApiVersion(params: {
993
+ id: string;
994
+ }, options?: CallOptions): Promise<WithServedVersion<JsonOk<"getApiVersion">>>;
995
+ toJSON(): Record<string, unknown>;
996
+ [INSPECT](): string;
997
+ toString(): string;
998
+ }
999
+
1000
+ export { type AllowanceRow, ApiError, type CallOptions, ClientCredentials, type ClientCredentialsOptions, type Clock, type CreateLessonPlanEvent, DEFAULT_BASE_URL, DEFAULT_TOKEN_URL, type DeprecationHook, type DeprecationNotice, EventStream, type FetchLike, type GenerateVocabularyEvent, type LessonPlan, type LessonPlanContent, type LessonPlanCreateRequest, Lingara, LingaraError, type LingaraOptions, MaintenanceError, type Notice, OAuthError, type PlanPending, type PlanPhase, type PlanResult, type PlanStarted, type PlanStatus, type SendTutorMessageEvent, type Sleeper, type StreamError, type StreamLessonPlanEvent, type TokenSource, TransportError, type TransportKind, type TurnDelta, type TutorTurnRequest, type Usage, type VersionDetail, type VersionList, type VersionState, type VersionSummary, type VocabExample, type VocabItem, type VocabMeta, type VocabRequest, type VocabStarted, type WithServedVersion, type Yielded, type components, type operations };