@startsimpli/llm 0.4.30 → 0.4.31

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 CHANGED
@@ -244,6 +244,45 @@ registerSpeechProvider('mine', () => (process.env.MINE_KEY ? new MyProvider(proc
244
244
  <<<<<<< HEAD
245
245
  so a new modality (TTS, embeddings) reuses it rather than hard-coding a provider list.
246
246
 
247
+ ### Voice cast library (`@startsimpli/llm/speech/voices`)
248
+
249
+ Voices keyed by neutral ids (never by avatar), with model, per-model settings, per-language rows, an emotion map, and the
250
+ retired / expiring ElevenLabs Default voice ids (they die 2026-12-31). Data is `src/speech/voices/cast-voices.json`.
251
+
252
+ ```ts
253
+ const cv = createCastVoices(defaultCastLibrary, { expiring: 'warn' }); // warn | allow | error; `today` injectable
254
+ const voices = cv.resolveCast([{ id: 'maya', voice: 'maya' }, { id: 'b' }], { language: 'es' });
255
+ const { textSent, settings } = directEmotion(cv, voices.b, 'Hello.', 'excited');
256
+ ```
257
+
258
+ A member's `voice` is a library id or a real voice id; anything else is an alias and the member takes the next `default_pool`
259
+ entry. Unfilled slot, retired / expiring id, unknown model or language, and two members on one voice throw named errors
260
+ (`VoiceNotResolvableError` subclasses). CLI: `echo '{"cast":[{"id":"a"}]}' | startsimpli-speech voices resolve [--model --language --expiring --today --library]`.
261
+
262
+ ### Captions (`@startsimpli/llm/speech/captions`)
263
+
264
+ Pure caption logic, no vendor and no I/O: `cuesFromWords` / `cuesFromText` / `cuesForBeat` (clause-aware splitting),
265
+ `holdGaps`, `cueFrameRange` (round half to even), `toSrt` / `toVtt`, and word checks: `wordsAreProportional` (is this
266
+ vendor alignment real or spread by character count?), `assertValidWords` (`InvalidWordsError` on empty or disordered
267
+ transcripts), `splitWhitespaceTokens`, `captionTiming`. Pixel and line-width layout stays with the renderer.
268
+ CLI: `startsimpli-speech captions --format json|srt|vtt [--out FILE] < request.json`.
269
+
270
+ ## Refine with gates (`@startsimpli/llm/refine`)
271
+
272
+ ```ts
273
+ const gates = createGateRegistry<Doc, Ctx>();
274
+ gates.register('schema', (doc, ctx) => validate(doc)); // string[] | { text, level: 'info' }[] , sync or async
275
+ const out = await refineWithGates({
276
+ step: llmRefineStep({ provider, systemPrompt, brief, validate }), // one model call per try; inject any client
277
+ gates, tries: 3, // an integer >= 1, or null to loop until every gate passes
278
+ });
279
+ // out.attempts[i] = { n, result, report, notes, cost, passed }; out.cost, out.tally, out.passed
280
+ ```
281
+
282
+ Each try is exactly one step call; the step receives the previous result and the gates' failures as data. Informational
283
+ lines (`level: 'info'`) never fail a gate. A step that throws ends the loop with `RefineStepError`. This is the multi-gate,
284
+ caller-bounded loop; `extractValidateCorrect` stays the single-validator JSON repair loop.
285
+
247
286
  ## Links
248
287
 
249
288
  - Source: https://github.com/qosha1/start-simpli/tree/main/packages/llm
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startsimpli/llm",
3
- "version": "0.4.30",
3
+ "version": "0.4.31",
4
4
  "description": "Generic LLM service infrastructure — provider abstraction, retry logic, JSON extraction",
5
5
  "license": "MIT",
6
6
  "homepage": "https://startsimpli.com",
@@ -17,7 +17,10 @@
17
17
  "exports": {
18
18
  ".": "./src/index.ts",
19
19
  "./translation": "./src/translation/index.ts",
20
- "./speech": "./src/speech/index.ts"
20
+ "./speech": "./src/speech/index.ts",
21
+ "./refine": "./src/refine/index.ts",
22
+ "./speech/voices": "./src/speech/voices/index.ts",
23
+ "./speech/captions": "./src/speech/captions/index.ts"
21
24
  },
22
25
  "files": [
23
26
  "src",