@jaypie/mcp 0.8.161 → 0.8.163
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/dist/assets.js +3 -3
- package/package.json +1 -1
- package/release-notes/jaypie/1.2.102.md +12 -0
- package/release-notes/jaypie/1.2.103.md +11 -0
- package/release-notes/llm/1.3.43.md +94 -0
- package/release-notes/llm/1.3.44.md +120 -0
- package/release-notes/mcp/0.8.162.md +15 -0
- package/release-notes/mcp/0.8.163.md +17 -0
- package/release-notes/testkit/1.2.75.md +12 -0
- package/release-notes/testkit/1.2.76.md +11 -0
- package/skills/llm.md +154 -1
package/dist/assets.js
CHANGED
|
@@ -55,11 +55,11 @@ function getMcpAssetPaths() {
|
|
|
55
55
|
*/
|
|
56
56
|
function getMcpBuildInfo() {
|
|
57
57
|
return {
|
|
58
|
-
commit: "
|
|
58
|
+
commit: "d5f7052e"
|
|
59
59
|
,
|
|
60
|
-
version: "0.8.
|
|
60
|
+
version: "0.8.163"
|
|
61
61
|
,
|
|
62
|
-
versionString: "@jaypie/mcp@0.8.
|
|
62
|
+
versionString: "@jaypie/mcp@0.8.163#d5f7052e"
|
|
63
63
|
,
|
|
64
64
|
};
|
|
65
65
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.102
|
|
3
|
+
date: 2026-09-18
|
|
4
|
+
summary: Pulls @jaypie/llm 1.3.43
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- **`@jaypie/llm` 1.3.43**: `Llm.question` answers typed questions in
|
|
10
|
+
TypeSafe's Jev shape, served natively by the new `typesafe` provider or
|
|
11
|
+
emulated on any provider that returns structured JSON. A per-call `model` no
|
|
12
|
+
longer follows `operate()` onto a fallback provider.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.103
|
|
3
|
+
date: 2026-09-19
|
|
4
|
+
summary: Pulls @jaypie/llm 1.3.44
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- **`@jaypie/llm` 1.3.44**: `Llm.ocr` extracts documents to per-page markdown
|
|
10
|
+
over Mistral OCR or the new `llamacloud` provider (LlamaParse), behind one
|
|
11
|
+
request and response shape with fallback across engines.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.3.43
|
|
3
|
+
date: 2026-09-18
|
|
4
|
+
summary: "Llm.question answers typed questions in TypeSafe's Jev shape, natively or emulated on any provider"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
### New Features
|
|
10
|
+
|
|
11
|
+
- `Llm.question(state, { questions })` is a fourth entry point, in TypeSafe's
|
|
12
|
+
(Jev's) shape: `noul`, `choice`, and `score` questions asked of a state,
|
|
13
|
+
answered one apiece with probabilities. Static and instance forms mirror
|
|
14
|
+
`operate`, including `model` array sugar, `fallback`, `retry`, `signal`, and
|
|
15
|
+
`user`.
|
|
16
|
+
- New provider `typesafe` serves TypeSafe's System One models over
|
|
17
|
+
`POST /v1/systemone`, with match words `jev` and `typesafe` and
|
|
18
|
+
`TYPESAFE_API_KEY`. It implements `question` only: a System One model
|
|
19
|
+
generates no text, so `send` throws `NotImplementedError` and the provider
|
|
20
|
+
offers no `operate` or `stream`. The client is `fetch` against the two
|
|
21
|
+
documented routes; no SDK dependency is taken.
|
|
22
|
+
- `MODEL.JEV` is `jev-1.13.0`, the versioned id the API echoes on every
|
|
23
|
+
response. The `jev-latest` and `jev-preview` aliases still route to the
|
|
24
|
+
provider through the match words. `COST["jev-1.13.0"]` is $0.042 input and
|
|
25
|
+
$0 output, which TypeSafe bills for answers.
|
|
26
|
+
- Every other provider answers the same call through an emulator: one
|
|
27
|
+
structured `operate()` call at `temperature: 0` and `turns: 1`, asking for
|
|
28
|
+
the full distribution, from which choice (argmax), score
|
|
29
|
+
(probability-weighted level index), and confidence are derived. A chain can
|
|
30
|
+
mix the two, so a rate-limited or unreachable Jev falls through to a
|
|
31
|
+
traditional model without the caller's request or response shape changing.
|
|
32
|
+
- The response carries `emulated`. When it is `true`, `probabilities` are
|
|
33
|
+
model-reported (normalized in code) and `confidence` is Jaypie's normalized
|
|
34
|
+
peak probability, `(max(p) - 1/n) / (1 - 1/n)`, exported as
|
|
35
|
+
`peakConfidence` alongside `normalizeDistribution`. TypeSafe has not
|
|
36
|
+
published its own formula; normalized peak reproduces both documented
|
|
37
|
+
examples and a live Jev call within rounding, and is replaced by TypeSafe's
|
|
38
|
+
when it publishes.
|
|
39
|
+
- TypeSafe's question limits (1 to 255 choice options, 2 to 10 ordered score
|
|
40
|
+
levels, non-empty instructions, `noul` criteria restricted to `true` and
|
|
41
|
+
`false`) are validated at the entry point for **every** provider, so a
|
|
42
|
+
question that validates is answerable anywhere in a chain. A violation
|
|
43
|
+
throws `BadRequestError` naming the question id.
|
|
44
|
+
|
|
45
|
+
### Mistral: dated ids, OCR 4.1, and the CI shard restored
|
|
46
|
+
|
|
47
|
+
- `MODEL.MISTRAL.LARGE` and `MODEL.MISTRAL.SMALL` name the dated ids
|
|
48
|
+
`mistral-large-2512` and `mistral-small-2603` in place of the `-latest`
|
|
49
|
+
aliases they resolved to. Prices are unchanged ($0.5/$1.5 and $0.15/$0.6,
|
|
50
|
+
cached input at 10%), and `COST[MODEL.MISTRAL.LARGE]` now hits rather than
|
|
51
|
+
missing by design: the catalog no longer names an alias.
|
|
52
|
+
- `MODEL.MISTRAL.OCR` moves to `mistral-ocr-4-1`. It stays unpriced in `COST`
|
|
53
|
+
because it bills per page ($4 per 1000 pages, $0.4 cached), which
|
|
54
|
+
`LlmModelCost` cannot express. Verified live against `POST /v1/ocr`.
|
|
55
|
+
- Mistral is a CI capability-matrix shard again, and `mistral-large-2512`
|
|
56
|
+
rejoins the live matrix. Both were dropped while the account's tier answered
|
|
57
|
+
every capability with "This model is not available in your subscription
|
|
58
|
+
tier"; on the upgraded tier both cataloged models pass all seven cells
|
|
59
|
+
(verified 2026-09-19).
|
|
60
|
+
|
|
61
|
+
### Bug Fixes
|
|
62
|
+
|
|
63
|
+
- The Anthropic hot spec streamed with `max_tokens: 64`. The 5-family models
|
|
64
|
+
open a response with a thinking block, so the budget was spent before any
|
|
65
|
+
text delta arrived and `streams text deltas` failed for Fable 5.1, Opus 5,
|
|
66
|
+
and Sonnet 5. The budget now accommodates the thinking block and the test
|
|
67
|
+
stops reading at the first text delta.
|
|
68
|
+
- A per-call `model` no longer follows `operate()` onto a fallback provider.
|
|
69
|
+
`operate(input, { model: ["gpt-5.6-luna", "claude-haiku-4-5"] })` sent the
|
|
70
|
+
primary model id to the fallback, asking Anthropic for an OpenAI model. Each
|
|
71
|
+
fallback now runs the model its own chain entry names.
|
|
72
|
+
|
|
73
|
+
### Internal
|
|
74
|
+
|
|
75
|
+
- The primary-then-chain loop moves to `src/util/runWithFallback.ts` and
|
|
76
|
+
serves both `operate` and `question`. Exchange settlement stays in
|
|
77
|
+
`operate`; `question` emits no exchange in this release.
|
|
78
|
+
- `MODEL.JEV` is excluded from the live capability matrix: a System One model
|
|
79
|
+
implements neither `operate()` nor `send()`, so every cell would fail by
|
|
80
|
+
construction.
|
|
81
|
+
|
|
82
|
+
## Testing
|
|
83
|
+
|
|
84
|
+
- Live, 2026-09-18 (`npm run test:llm:question`): all three question types
|
|
85
|
+
against `jev-1.13.0` natively and against `claude-haiku-4-5` and
|
|
86
|
+
`gpt-5.6-luna` by emulation, plus a chain falling from an unknown Jev model
|
|
87
|
+
to emulation. 4 of 4 passed, with the three models agreeing on every answer
|
|
88
|
+
(choice `billing`; noul 0.97, 0.92, 0.98; score 1.86, 1.60, 1.83 on a 0 to 2
|
|
89
|
+
scale).
|
|
90
|
+
- New unit coverage for validation, the emulator (prompt, schema,
|
|
91
|
+
normalization, argmax, weighted score, confidence against TypeSafe's
|
|
92
|
+
documented examples), `Llm.question` fallback behavior, the TypeSafe client's
|
|
93
|
+
status-to-error mapping, and provider routing. A hot spec exercises both
|
|
94
|
+
live routes when `TYPESAFE_API_KEY` is set.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.3.44
|
|
3
|
+
date: 2026-09-19
|
|
4
|
+
summary: "Llm.ocr extracts documents to per-page markdown over Mistral OCR or LlamaParse behind one shape"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
### New Features
|
|
10
|
+
|
|
11
|
+
- `Llm.ocr(document, options?)` is a fifth entry point: a document in,
|
|
12
|
+
per-page markdown out. Static and instance forms mirror `question`,
|
|
13
|
+
including `model` array sugar, `fallback`, `retry`, and `signal`. The
|
|
14
|
+
document (an `https://` URL, a `data:` URI, an S3 key, a local path, or the
|
|
15
|
+
`{ file }` / `{ image }` objects `operate()` accepts) is resolved once before
|
|
16
|
+
the fallback chain runs.
|
|
17
|
+
- New provider `llamacloud` serves LlamaParse over the LlamaCloud Parse API
|
|
18
|
+
v2 with `LLAMA_CLOUD_API_KEY` and match words `llamacloud`, `llamaindex`,
|
|
19
|
+
and `llamaparse`. A parse is a job: submitted by `source_url` or multipart
|
|
20
|
+
upload, polled from one second backing off to five, then fetched. It
|
|
21
|
+
implements `ocr` only; `send` throws `NotImplementedError`. The client is
|
|
22
|
+
`fetch` against four routes; no SDK dependency is taken.
|
|
23
|
+
- The LlamaParse **tier is the model id**: `MODEL.LLAMAPARSE.FAST`,
|
|
24
|
+
`COST_EFFECTIVE`, `AGENTIC` (the provider default), and `AGENTIC_PLUS`.
|
|
25
|
+
A chain such as `[MODEL.MISTRAL.OCR, MODEL.LLAMAPARSE.COST_EFFECTIVE]`
|
|
26
|
+
therefore reads as a plain model list and routes through
|
|
27
|
+
`determineModelProvider`.
|
|
28
|
+
- The API version is pinned per tier in `PROVIDER.LLAMACLOUD.VERSION`; each
|
|
29
|
+
tier accepts its own dated versions and rejects the others (verified live
|
|
30
|
+
2026-09-19). `providerOptions.version` overrides it per call, and the
|
|
31
|
+
response `model` is `<tier id>@<version>`.
|
|
32
|
+
- Common shape: `markdown`, 1-indexed `pages[]` with `header`, `footer`,
|
|
33
|
+
`images`, `success`/`error`, and the vendor page at `raw`; `images[]`;
|
|
34
|
+
`usage` with `pages`, LlamaParse `credits`, and `cost`; `responses[]`; and
|
|
35
|
+
the `provider`/`model`/`fallbackAttempts`/`fallbackUsed` fields `operate`
|
|
36
|
+
carries. Options: `pages` (`[1, 3]` or `"1,3,5-10"`), `tables`
|
|
37
|
+
(`"markdown"` or `"html"`), `images` (download extracted images as `data:`
|
|
38
|
+
URIs), `timeout` (asynchronous job ceiling, default ten minutes), and
|
|
39
|
+
`providerOptions` spread last onto the vendor request.
|
|
40
|
+
- `PAGE_COST` prices document-extraction engines in USD per 1,000 pages,
|
|
41
|
+
keyed by literal id: `mistral-ocr-4-1` at $4 and the four LlamaParse tiers
|
|
42
|
+
at $1.25, $3.75, $12.50, and $56.25 (credits at
|
|
43
|
+
`PROVIDER.LLAMACLOUD.CREDIT_COST`, $1.25 per 1,000). A LlamaParse job's
|
|
44
|
+
recorded credits win over the per-page estimate.
|
|
45
|
+
- `DEFAULT.OCR` names the engine `Llm.ocr` uses when neither a provider nor a
|
|
46
|
+
model is given: Mistral OCR, one synchronous call and the cheapest markdown
|
|
47
|
+
tier on offer.
|
|
48
|
+
- **OCR emulation on chat models**, as `question` emulates: a provider with
|
|
49
|
+
`operate` but no `ocr` transcribes through `src/ocr/OcrEmulator.ts`, so a
|
|
50
|
+
chain such as `[MODEL.MISTRAL.OCR, MODEL.HAIKU]` falls from a native engine
|
|
51
|
+
to any model that accepts files. Each page rides alone in one structured
|
|
52
|
+
`operate()` call (a PDF is trimmed to one page per request, so the model
|
|
53
|
+
never counts or numbers pages), under a fixed `{ confidence, markdown,
|
|
54
|
+
notes }` schema and a verbatim-transcription prompt with `[UNCLEAR: …]` and
|
|
55
|
+
`[ELEMENT: …]` markers. A page scored under 0.4 is transcribed once more
|
|
56
|
+
and the higher score wins. `concurrency` (default 5) bounds pages in
|
|
57
|
+
flight; the first failure aborts the rest and rethrows so the next engine
|
|
58
|
+
starts clean, and unreadable content throws `InternalError` to the same
|
|
59
|
+
end. The response carries `emulated: true`, `pages[].confidence`,
|
|
60
|
+
`usage.tokens`, and `usage.cost` priced from `COST` through the new
|
|
61
|
+
`tokenCost` helper. `user` forwards to the calls. A provider with neither
|
|
62
|
+
(`typesafe`) fails its attempt and the chain moves on.
|
|
63
|
+
- `LlmOcrResponse.emulated` is present on every response (`false` from a
|
|
64
|
+
native engine), matching `LlmQuestionResponse`.
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- `MistralProvider.ocr()` takes the common `(document, options)` signature
|
|
69
|
+
and returns the common shape. The provider-specific `{ markdown, model,
|
|
70
|
+
pages, raw }` return shipped in 1.3.43 and is gone: `raw` is
|
|
71
|
+
`responses[0]`, and the 0-indexed `pages[].index` is the 1-indexed
|
|
72
|
+
`pages[].page` with the vendor page at `pages[].raw`. `MistralOcrPage` and
|
|
73
|
+
`MistralOcrResponse` are no longer exported. `OcrRequest` widens to the full
|
|
74
|
+
Mistral `OCRRequest` field set.
|
|
75
|
+
- Client failures on Mistral OCR classify through the chat adapter into the
|
|
76
|
+
typed `LlmError` family, and both engines share one retry loop
|
|
77
|
+
(`src/ocr/runOcrAttempts.ts`), so `retry` and `signal` mean the same thing
|
|
78
|
+
on each. A LlamaParse job that reports `FAILED` throws
|
|
79
|
+
`LlmUnrecoverableError` with the API's message, `CANCELLED` throws
|
|
80
|
+
`LlmAbortError`, and a job that outlives `timeout` throws
|
|
81
|
+
`LlmTransientError` so a chain can try the next engine.
|
|
82
|
+
- `loadFileData` and `getExtensionForMimeType` are exported from the upload
|
|
83
|
+
helpers for reuse; `LlmProvider` gains an optional `ocr`.
|
|
84
|
+
- `extractPdfPages` throws `BadRequestError` on an out-of-range page where it
|
|
85
|
+
threw a vanilla `Error`.
|
|
86
|
+
|
|
87
|
+
### Internal
|
|
88
|
+
|
|
89
|
+
- `MODEL.LLAMAPARSE.*` join `MODEL.MISTRAL.OCR` in `MATRIX_EXCLUDE`: a
|
|
90
|
+
document-extraction engine implements neither `operate()` nor `send()`, so
|
|
91
|
+
every capability cell would fail by construction. They are exercised by
|
|
92
|
+
`tsx test/ocr.ts` (`npm run test:llm:ocr`) and the provider hot specs.
|
|
93
|
+
- Both CI workflows pass `LLAMA_CLOUD_API_KEY` from the
|
|
94
|
+
`CICD_LLAMA_CLOUD_API_KEY` org secret; the LlamaCloud hot spec skips until
|
|
95
|
+
the secret exists.
|
|
96
|
+
|
|
97
|
+
## Testing
|
|
98
|
+
|
|
99
|
+
- Live, 2026-09-19 (`npm run test:llm:ocr`): `page.pdf` and `page.png`
|
|
100
|
+
through Mistral OCR and all four LlamaParse tiers, every run reading the
|
|
101
|
+
fixture text, plus a chain falling from an unknown tier to Mistral. 11 of 11
|
|
102
|
+
passed. Mistral answered in about one second at $0.004 per page; LlamaParse
|
|
103
|
+
completed in 3 to 5 polls (6 to 15 seconds) at 1, 3, 10, and 45 credits per
|
|
104
|
+
page by tier.
|
|
105
|
+
- Live, 2026-09-19, with emulation: the same fixtures through Haiku and
|
|
106
|
+
Luna, plus a chain falling from an unknown tier into Haiku. 15 of 15
|
|
107
|
+
passed. Haiku transcribed a page in 1.5 to 2.5 seconds for $0.0015 to
|
|
108
|
+
$0.0026 (1,200 to 2,200 tokens) at 0.95 confidence; Luna in 1 to 3 seconds
|
|
109
|
+
for $0.0002 to $0.0003 at 0.98 to 0.99. Both marked the fixture's rule as
|
|
110
|
+
`---` or `[ELEMENT: decorative horizontal line]`; Luna read the PDF's
|
|
111
|
+
heading last, where every other engine read it first.
|
|
112
|
+
- New unit coverage for page-selection parsing, document resolution (URL,
|
|
113
|
+
data URI, S3, disk, inline data, PDF trimming), the shared retry loop, the
|
|
114
|
+
LlamaCloud client's routes and status-to-error mapping, the provider's
|
|
115
|
+
submit/poll/fetch cycle (including fast-tier text, failed pages, image
|
|
116
|
+
download, per-tier version, timeout, and abort), the reworked Mistral OCR
|
|
117
|
+
mapping, `Llm.ocr` routing and fallback (native to emulated and back),
|
|
118
|
+
the emulator (page splitting, selection, image and URL input, low-confidence
|
|
119
|
+
re-transcription, concurrency cap, first-failure abort, caller abort, and
|
|
120
|
+
fetch classification), `tokenCost`, and provider routing for every new id.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.162
|
|
3
|
+
date: 2026-09-18
|
|
4
|
+
summary: Document Llm.question and the TypeSafe provider in the llm skill
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
### Documentation
|
|
10
|
+
|
|
11
|
+
- `skills/llm.md` gains a "Questions (Jev Shape)" section: the three question
|
|
12
|
+
types and their answers, the response fields, what `emulated` means for
|
|
13
|
+
`confidence`, and how chains mix native and emulated providers.
|
|
14
|
+
- The providers table carries a `typesafe` row, and the environment block
|
|
15
|
+
carries `TYPESAFE_API_KEY`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.163
|
|
3
|
+
date: 2026-09-19
|
|
4
|
+
summary: Document Llm.ocr and the LlamaCloud provider in the llm skill
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
### Documentation
|
|
10
|
+
|
|
11
|
+
- `skills/llm.md` gains an "OCR" section: the document forms `Llm.ocr`
|
|
12
|
+
accepts, the page and usage shape, `pages`/`tables`/`images`/`timeout`/
|
|
13
|
+
`providerOptions`, per-tier LlamaParse versions, and fallback across
|
|
14
|
+
engines.
|
|
15
|
+
- The providers table carries a `llamacloud` row, the model constants name
|
|
16
|
+
`MODEL.LLAMAPARSE.*` and `PAGE_COST`, and the environment block carries
|
|
17
|
+
`LLAMA_CLOUD_API_KEY`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.75
|
|
3
|
+
date: 2026-09-18
|
|
4
|
+
summary: Mock Llm.question and the TypeSafe provider
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- `Llm.question` (static, instance, and on the inner provider) resolves a
|
|
10
|
+
mock question response with one `choice` answer and `emulated: false`.
|
|
11
|
+
- New mocks: `TypeSafeProvider`, `TypeSafeClient`, `LlmQuestionType`,
|
|
12
|
+
`normalizeDistribution`, and `peakConfidence`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.76
|
|
3
|
+
date: 2026-09-19
|
|
4
|
+
summary: Mock Llm.ocr and the LlamaCloud provider
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- `Llm.ocr` (static, instance, and on the inner provider) resolves a mock OCR
|
|
10
|
+
response with one page of `_MOCK_OCR_MARKDOWN`.
|
|
11
|
+
- New mocks: `LlamaCloudProvider` and `LlamaCloudClient`.
|
package/skills/llm.md
CHANGED
|
@@ -41,6 +41,8 @@ the alias rather than the id it currently resolves to. Read the id off
|
|
|
41
41
|
| xAI | "xai", "grok" | `MODEL.GROK` |
|
|
42
42
|
| Meta | "muse" (plus the exact name `meta` and a `meta:` prefix) | `MODEL.MUSE_SPARK` |
|
|
43
43
|
| Bedrock | "amazon.nova", "anthropic.claude", "meta.llama", "deepseek.", "google.gemma", "moonshotai.", "openai.gpt-oss", … | `MODEL.NOVA_PRO` |
|
|
44
|
+
| TypeSafe | "jev", "typesafe" | `MODEL.JEV` |
|
|
45
|
+
| LlamaCloud | "llamacloud", "llamaindex", "llamaparse" | `MODEL.LLAMAPARSE.AGENTIC` |
|
|
44
46
|
|
|
45
47
|
The provider name for Gemini models is `"google"` — `"gemini"` is accepted as a deprecated alias.
|
|
46
48
|
|
|
@@ -48,10 +50,14 @@ Mistral's family names mostly do not contain the substring "mistral" (`ministral
|
|
|
48
50
|
|
|
49
51
|
"meta" is deliberately not a Meta match word: `meta.llama-*` is a Bedrock id and `meta-llama/*` an OpenRouter route. Muse Spark ids resolve on "muse"; use the `meta:` prefix to force the Meta Model API for any other id.
|
|
50
52
|
|
|
53
|
+
TypeSafe serves System One models (Jev), which answer typed questions and generate no text. The provider implements `question()` only: `operate()`, `send()`, and `stream()` throw. See [Questions](#questions-jev-shape).
|
|
54
|
+
|
|
55
|
+
LlamaCloud serves LlamaParse, which extracts documents and generates no text. The provider implements `ocr()` only. The parse tier is the model id (`MODEL.LLAMAPARSE.FAST`, `COST_EFFECTIVE`, `AGENTIC`, `AGENTIC_PLUS`). See [OCR](#ocr).
|
|
56
|
+
|
|
51
57
|
### Model Constants
|
|
52
58
|
|
|
53
59
|
- **`PROVIDER.<name>.DEFAULT`** — the single default model per provider (above), used when no `model` is given.
|
|
54
|
-
- **`LLM.MODEL.*`** — the named model catalog (e.g. `MODEL.SONNET`, `MODEL.ASTRA`, `MODEL.SOL`, `MODEL.GEMINI_FLASH`, `MODEL.GROK`, `MODEL.MUSE_SPARK`, `MODEL.MUSE_SPARK_CONTRIBUTOR`, `MODEL.NOVA_PRO`, `MODEL.NOVA_LITE`), plus three nested subtrees: `MODEL.FIREWORKS.*` for Fireworks serverless models (`DEEPSEEK`, `GLM`, `GPT_OSS`, `INKLING`, `KIMI`, `MINIMAX`, `NEMOTRON`, `QWEN`), `MODEL.MISTRAL.*` (`LARGE`, `OCR`, `SMALL`), and `MODEL.OPENROUTER.*` for provider-prefixed routes (`GLM`, `LUNA`, `SONNET`). Pick specific models from here. `MODEL.MISTRAL.OCR`
|
|
60
|
+
- **`LLM.MODEL.*`** — the named model catalog (e.g. `MODEL.SONNET`, `MODEL.ASTRA`, `MODEL.SOL`, `MODEL.GEMINI_FLASH`, `MODEL.GROK`, `MODEL.MUSE_SPARK`, `MODEL.MUSE_SPARK_CONTRIBUTOR`, `MODEL.NOVA_PRO`, `MODEL.NOVA_LITE`), plus three nested subtrees: `MODEL.FIREWORKS.*` for Fireworks serverless models (`DEEPSEEK`, `GLM`, `GPT_OSS`, `INKLING`, `KIMI`, `MINIMAX`, `NEMOTRON`, `QWEN`), `MODEL.MISTRAL.*` (`LARGE`, `OCR`, `SMALL`), `MODEL.LLAMAPARSE.*` for LlamaParse tiers (`FAST`, `COST_EFFECTIVE`, `AGENTIC`, `AGENTIC_PLUS`), and `MODEL.OPENROUTER.*` for provider-prefixed routes (`GLM`, `LUNA`, `SONNET`). Pick specific models from here. `MODEL.MISTRAL.OCR` and `MODEL.LLAMAPARSE.*` are document-extraction engines reached through `Llm.ocr`, not chat completions: they are priced per page in `LLM.PAGE_COST` (USD per 1,000 pages, keyed by literal id) and carry no `COST` entry. Amazon's Nova models are first-class ids served over Bedrock; Bedrock's third-party routes are not catalogued — pass the literal id (e.g. `us.anthropic.claude-sonnet-4-6`) and `determineModelProvider` resolves it to `bedrock`.
|
|
55
61
|
- `MODEL.MUSE_SPARK` and `MODEL.MUSE_SPARK_CONTRIBUTOR` are the same Meta model at two tiers. The contributor tier is roughly a tenth of the price because prompts and completions may train Meta models; it is limited to 100 RPM and does not accept `reasoning.effort: "max"`. It is an explicit opt-in: `PROVIDER.META.DEFAULT` is `MODEL.MUSE_SPARK`.
|
|
56
62
|
- The catalog is the **single source of truth for CI coverage**: `packages/llm/test/models.ts` derives the live capability matrix from `MODEL.*` plus each `PROVIDER.*.DEFAULT`, and the workflow shards it by provider. Adding a model to `MODEL.*` puts it under test; no id list exists anywhere else.
|
|
57
63
|
- **Deprecated:** the size-tier map `PROVIDER.<name>.MODEL.{DEFAULT,LARGE,SMALL,TINY}`, the `DEFAULT.MODEL` bundle, and `ALL` are `@deprecated` and retired in 2.0 — use `PROVIDER.*.DEFAULT` for defaults and `MODEL.*` for named models.
|
|
@@ -401,6 +407,151 @@ jsonSchemaToNaturalSchema({
|
|
|
401
407
|
|
|
402
408
|
`naturalSchemaToJsonSchema` is lossless — Natural Schema is a strict subset of JSON Schema. `jsonSchemaToNaturalSchema` is lossy: JSON Schema constraints, descriptions, defaults, unions, and optionality have no Natural Schema equivalent and are dropped. It never throws; every dropped keyword is logged at `log.debug` with the keyword name and JSON path.
|
|
403
409
|
|
|
410
|
+
## Questions (Jev Shape)
|
|
411
|
+
|
|
412
|
+
`Llm.question(state, { questions })` asks typed questions about a body of
|
|
413
|
+
text and returns one typed answer each, with probabilities. The request and
|
|
414
|
+
response shapes are TypeSafe's, so a question written once is answered the
|
|
415
|
+
same way by every provider: TypeSafe's System One models (Jev) answer
|
|
416
|
+
natively, and every other provider answers through an emulator that rigs up
|
|
417
|
+
one structured `operate()` call. Traditional models fit the question shape;
|
|
418
|
+
the question shape does not bend to fit them.
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { Llm, LLM } from "@jaypie/llm";
|
|
422
|
+
|
|
423
|
+
const { answers, emulated } = await Llm.question(ticket, {
|
|
424
|
+
model: [LLM.MODEL.JEV, LLM.MODEL.HAIKU], // native first, emulated if Jev is down
|
|
425
|
+
questions: {
|
|
426
|
+
department: {
|
|
427
|
+
type: "choice",
|
|
428
|
+
instructions: "Which team should handle this?",
|
|
429
|
+
criteria: {
|
|
430
|
+
billing: "Charges, invoices, refunds",
|
|
431
|
+
sales: null, // the option name speaks for itself
|
|
432
|
+
technical: "Bugs, outages",
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
is_urgent: { type: "noul", instructions: "Does this convey urgency?" },
|
|
436
|
+
frustration: {
|
|
437
|
+
type: "score",
|
|
438
|
+
instructions: "How frustrated is the customer?",
|
|
439
|
+
criteria: ["Calm", "Frustrated", "Very angry"], // 2 to 10, lowest first
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
answers.department; // { type: "choice", choice: "billing", confidence: 0.98, probabilities: {...} }
|
|
445
|
+
answers.is_urgent; // { type: "noul", noul: 0.94 }
|
|
446
|
+
answers.frustration; // { type: "score", score: 1.7, confidence: 0.56, legend: {...}, probabilities: {...} }
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### Question Types
|
|
450
|
+
|
|
451
|
+
| Type | Criteria | Answer |
|
|
452
|
+
|------|----------|--------|
|
|
453
|
+
| `noul` | optional `{ true, false }` descriptions | `{ type, noul }` — probability 0 to 1, no confidence: the number is the degree of belief |
|
|
454
|
+
| `choice` | `Record<option, description \| null>`, 1 to 255 options | `{ type, choice, confidence, probabilities }` — `choice` is the argmax, `probabilities` keyed by option name |
|
|
455
|
+
| `score` | ordered `string[]`, 2 to 10 levels lowest first | `{ type, score, confidence, legend, probabilities }` — `score` is the probability-weighted level index, `legend` and `probabilities` keyed by level index as a string |
|
|
456
|
+
|
|
457
|
+
`instructions` and every criteria value accept a string, an object, or an
|
|
458
|
+
array. `state` accepts the same three and is text only: no files, no images,
|
|
459
|
+
no conversation. Question ids are the caller's and never reach the model.
|
|
460
|
+
TypeSafe's limits are enforced on every provider at the entry point, so a
|
|
461
|
+
question that validates works anywhere in a chain; a violation throws
|
|
462
|
+
`BadRequestError` naming the question id.
|
|
463
|
+
|
|
464
|
+
### Response
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
{
|
|
468
|
+
answers, // Record<question id, answer>
|
|
469
|
+
emulated, // false when a System One model answered natively
|
|
470
|
+
fallbackAttempts, // providers tried (1 = primary only)
|
|
471
|
+
fallbackUsed,
|
|
472
|
+
model, // the versioned id that served the request
|
|
473
|
+
provider,
|
|
474
|
+
responses, // raw provider payloads
|
|
475
|
+
usage, // LlmUsage, same shape operate() reports
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
`emulated: true` marks an answer a traditional model produced. Its
|
|
480
|
+
`probabilities` are model-reported (normalized in code) and its `confidence`
|
|
481
|
+
is a Jaypie statistic over them — normalized peak probability,
|
|
482
|
+
`(max(p) - 1/n) / (1 - 1/n)`, exported as `peakConfidence` — not a calibrated
|
|
483
|
+
System One output. Threshold on it knowing that.
|
|
484
|
+
|
|
485
|
+
Chains work exactly as they do for `operate()`: `model` accepts a
|
|
486
|
+
preference-ordered array, `fallback` accepts explicit entries or `false`, and
|
|
487
|
+
an attempt with somewhere left to go skips the rate-limit wait. A provider
|
|
488
|
+
that can neither `question` nor `operate` counts as a failed attempt and the
|
|
489
|
+
chain moves on.
|
|
490
|
+
|
|
491
|
+
## OCR
|
|
492
|
+
|
|
493
|
+
`Llm.ocr(document, options?)` turns a document into per-page markdown. Two
|
|
494
|
+
engines answer natively behind one request and response shape: Mistral OCR
|
|
495
|
+
(`MODEL.MISTRAL.OCR`, one synchronous call, the default when no provider or
|
|
496
|
+
model is named) and LlamaParse over LlamaCloud (`MODEL.LLAMAPARSE.*`, a job
|
|
497
|
+
that is submitted, polled, and fetched; `LLAMA_CLOUD_API_KEY`). Every other
|
|
498
|
+
provider answers through emulation, as `Llm.question` does: one structured
|
|
499
|
+
`operate()` call per page. A `model` array is therefore a fallback chain
|
|
500
|
+
across native engines and chat models alike.
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
import { Llm, LLM } from "@jaypie/llm";
|
|
504
|
+
|
|
505
|
+
const { emulated, markdown, pages, usage } = await Llm.ocr(
|
|
506
|
+
"./scans/invoice.pdf",
|
|
507
|
+
{
|
|
508
|
+
model: [
|
|
509
|
+
LLM.MODEL.MISTRAL.OCR,
|
|
510
|
+
LLM.MODEL.LLAMAPARSE.COST_EFFECTIVE,
|
|
511
|
+
LLM.MODEL.HAIKU, // emulated: any provider that accepts files
|
|
512
|
+
],
|
|
513
|
+
pages: "1,3-5", // 1-indexed; [1, 3, 4, 5] also works
|
|
514
|
+
tables: "markdown", // or "html"
|
|
515
|
+
},
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
pages[0].page; // 1
|
|
519
|
+
pages[0].markdown;
|
|
520
|
+
pages[0].confidence; // emulated only: the model's self-reported 0..1
|
|
521
|
+
emulated; // true when a chat model transcribed the pages
|
|
522
|
+
usage.pages; // pages billed
|
|
523
|
+
usage.cost; // USD from LLM.PAGE_COST (LlamaParse: from recorded credits; emulated: from COST tokens)
|
|
524
|
+
usage.tokens; // emulated only: every operate() call's usage
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
Emulation sends each page alone (a PDF is trimmed to one page per call, so
|
|
528
|
+
the model never numbers pages), asks for verbatim Markdown with
|
|
529
|
+
`[UNCLEAR: best guess]` and `[ELEMENT: description]` markers, transcribes a
|
|
530
|
+
page scored under 0.4 once more and keeps the higher score, and runs
|
|
531
|
+
`concurrency` pages at a time (default 5); the first failure stops the rest
|
|
532
|
+
so the next engine starts clean. Unreadable content fails the attempt so the
|
|
533
|
+
chain moves on. A provider with native `ocr` (Mistral) always answers
|
|
534
|
+
natively; a provider with neither `ocr` nor `operate` (`typesafe`) fails its
|
|
535
|
+
attempt and the chain moves on.
|
|
536
|
+
|
|
537
|
+
`document` is an `https://` URL (fetched by the vendor), a `data:` URI, an S3
|
|
538
|
+
key (when `CDK_ENV_BUCKET` is set), a local path, or the `{ file, bucket?,
|
|
539
|
+
data?, pages? }` / `{ image, ... }` objects `operate()` accepts. Set
|
|
540
|
+
`images: true` to download extracted images as `data:` URIs onto
|
|
541
|
+
`images[]` and `pages[].images`. `providerOptions` spreads last onto the
|
|
542
|
+
vendor request: Mistral `OCRRequest` fields (`document_annotation_format`,
|
|
543
|
+
`include_blocks`, ...) or LlamaParse `ParseRequestConfiguration` fields
|
|
544
|
+
(`version`, `agentic_options.custom_prompt`, `processing_options`,
|
|
545
|
+
`output_options`, `disable_cache`, ...). `timeout` (default ten minutes)
|
|
546
|
+
bounds a LlamaParse job; expiry throws `LlmTransientError` so a chain can try
|
|
547
|
+
the next engine. `retry` and `signal` behave as on `operate()`.
|
|
548
|
+
|
|
549
|
+
LlamaParse's API version is pinned per tier in `PROVIDER.LLAMACLOUD.VERSION`
|
|
550
|
+
(each tier accepts its own dated versions); the response `model` reads
|
|
551
|
+
`llamaparse-agentic@2026-09-13` so usage records name the configuration. The
|
|
552
|
+
fast tier returns text only, copied into `markdown`. Failed pages arrive with
|
|
553
|
+
`success: false` and `error` rather than failing the call.
|
|
554
|
+
|
|
404
555
|
## Conversation History
|
|
405
556
|
|
|
406
557
|
Continue conversations across calls:
|
|
@@ -649,6 +800,8 @@ OPENAI_API_KEY # Required for OpenAI
|
|
|
649
800
|
OPENROUTER_API_KEY # Required for OpenRouter
|
|
650
801
|
XAI_API_KEY # Required for xAI (Grok)
|
|
651
802
|
META_API_KEY # Required for Meta (Muse Spark); MODEL_API_KEY is read as a fallback
|
|
803
|
+
TYPESAFE_API_KEY # Required for TypeSafe (Jev); emulated questions use the answering provider's key
|
|
804
|
+
LLAMA_CLOUD_API_KEY # Required for LlamaParse (Llm.ocr); Mistral OCR uses MISTRAL_API_KEY
|
|
652
805
|
```
|
|
653
806
|
|
|
654
807
|
Keys are resolved via `getEnvSecret()` which supports AWS Secrets Manager.
|