@gullabs/any-llm 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -20,6 +20,7 @@ This installs the core engine, Gemini adapter, and `@google/genai`.
20
20
  ```ts
21
21
  import {
22
22
  createClient,
23
+ defaultGeminiRegistry,
23
24
  defineCallSite,
24
25
  geminiAdapter,
25
26
  geminiPricingSource,
@@ -50,8 +51,22 @@ const result = await client.runStructured(
50
51
  { text: documentText },
51
52
  { auth: { apiKey: process.env.GEMINI_API_KEY! } },
52
53
  )
54
+
55
+ const descriptor = defaultGeminiRegistry.resolve('gemini-3.5-flash')
56
+ if (!descriptor) throw new Error('unknown model')
57
+
58
+ const parsedConfig = descriptor.configSchema.parse({
59
+ reasoning: { effort: 'medium' },
60
+ })
53
61
  ```
54
62
 
63
+ Built-in descriptors own the strict model-config contract:
64
+ `descriptor.configSchema` parses persisted or user-supplied config, and
65
+ `descriptor.configJsonSchema` is the derived UI/form schema. Use
66
+ `reasoning.effort` for Gemini 3 and Gemma built-ins, omit `serviceTier` for the
67
+ provider's standard tier, and set `flex` explicitly when that trade-off is
68
+ intended. `priority` remains rejected by the library for now.
69
+
55
70
  ## Key exports
56
71
 
57
72
  This package re-exports the full public API of `@gullabs/core` and `@gullabs/google` verbatim —
package/dist/index.cjs CHANGED
@@ -6,7 +6,7 @@ var google = require('@gullabs/google');
6
6
  // src/index.ts
7
7
 
8
8
  // package.json
9
- var version = "0.5.1";
9
+ var version = "0.6.0";
10
10
 
11
11
  // src/index.ts
12
12
  var ANY_LLM_VERSION = version;
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/index.ts"],"names":[],"mappings":";;;;;;;;AAEE,IAAA,OAAA,GAAW,OAAA;;;ACcN,IAAM,eAAA,GAA0B","file":"index.cjs","sourcesContent":["{\n \"name\": \"@gullabs/any-llm\",\n \"version\": \"0.5.1\",\n \"description\": \"Batteries-included any-llm client for Gemini: engine, adapter, and Google SDK in one install.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/gullabs/any-llm.git\",\n \"directory\": \"packages/any-llm\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\",\n \"skills\"\n ],\n \"scripts\": {\n \"build\": \"tsup\"\n },\n \"dependencies\": {\n \"@google/genai\": \"^1.45.0 || ^2\",\n \"@gullabs/core\": \"workspace:*\",\n \"@gullabs/google\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=20.9.0\"\n },\n \"sideEffects\": false,\n \"keywords\": [\n \"llm\",\n \"gemini\",\n \"google-genai\",\n \"ai\",\n \"tokens\",\n \"cost\",\n \"usage\",\n \"observability\",\n \"typescript\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"homepage\": \"https://github.com/gullabs/any-llm/tree/main/packages/any-llm#readme\",\n \"bugs\": \"https://github.com/gullabs/any-llm/issues\"\n}\n","/**\n * @gullabs/any-llm — batteries-included public entrypoint.\n *\n * This package is the default client install path. It re-exports the core\n * engine and Gemini adapter while depending on the Gemini SDK for a one-package\n * setup.\n *\n * @module\n */\n\nexport * from '@gullabs/core'\nexport * from '@gullabs/google'\n\nimport { version } from '../package.json'\n\n/** Library version, sourced from package.json at build time. */\nexport const ANY_LLM_VERSION: string = version\n"]}
1
+ {"version":3,"sources":["../package.json","../src/index.ts"],"names":[],"mappings":";;;;;;;;AAEE,IAAA,OAAA,GAAW,OAAA;;;ACcN,IAAM,eAAA,GAA0B","file":"index.cjs","sourcesContent":["{\n \"name\": \"@gullabs/any-llm\",\n \"version\": \"0.6.0\",\n \"description\": \"Batteries-included any-llm client for Gemini: engine, adapter, and Google SDK in one install.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/gullabs/any-llm.git\",\n \"directory\": \"packages/any-llm\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\",\n \"skills\"\n ],\n \"scripts\": {\n \"build\": \"tsup\"\n },\n \"dependencies\": {\n \"@google/genai\": \"^1.45.0 || ^2\",\n \"@gullabs/core\": \"workspace:*\",\n \"@gullabs/google\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=20.9.0\"\n },\n \"sideEffects\": false,\n \"keywords\": [\n \"llm\",\n \"gemini\",\n \"google-genai\",\n \"ai\",\n \"tokens\",\n \"cost\",\n \"usage\",\n \"observability\",\n \"typescript\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"homepage\": \"https://github.com/gullabs/any-llm/tree/main/packages/any-llm#readme\",\n \"bugs\": \"https://github.com/gullabs/any-llm/issues\"\n}\n","/**\n * @gullabs/any-llm — batteries-included public entrypoint.\n *\n * This package is the default client install path. It re-exports the core\n * engine and Gemini adapter while depending on the Gemini SDK for a one-package\n * setup.\n *\n * @module\n */\n\nexport * from '@gullabs/core'\nexport * from '@gullabs/google'\n\nimport { version } from '../package.json'\n\n/** Library version, sourced from package.json at build time. */\nexport const ANY_LLM_VERSION: string = version\n"]}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ export * from '@gullabs/google';
4
4
  // src/index.ts
5
5
 
6
6
  // package.json
7
- var version = "0.5.1";
7
+ var version = "0.6.0";
8
8
 
9
9
  // src/index.ts
10
10
  var ANY_LLM_VERSION = version;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/index.ts"],"names":[],"mappings":";;;;;;AAEE,IAAA,OAAA,GAAW,OAAA;;;ACcN,IAAM,eAAA,GAA0B","file":"index.js","sourcesContent":["{\n \"name\": \"@gullabs/any-llm\",\n \"version\": \"0.5.1\",\n \"description\": \"Batteries-included any-llm client for Gemini: engine, adapter, and Google SDK in one install.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/gullabs/any-llm.git\",\n \"directory\": \"packages/any-llm\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\",\n \"skills\"\n ],\n \"scripts\": {\n \"build\": \"tsup\"\n },\n \"dependencies\": {\n \"@google/genai\": \"^1.45.0 || ^2\",\n \"@gullabs/core\": \"workspace:*\",\n \"@gullabs/google\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=20.9.0\"\n },\n \"sideEffects\": false,\n \"keywords\": [\n \"llm\",\n \"gemini\",\n \"google-genai\",\n \"ai\",\n \"tokens\",\n \"cost\",\n \"usage\",\n \"observability\",\n \"typescript\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"homepage\": \"https://github.com/gullabs/any-llm/tree/main/packages/any-llm#readme\",\n \"bugs\": \"https://github.com/gullabs/any-llm/issues\"\n}\n","/**\n * @gullabs/any-llm — batteries-included public entrypoint.\n *\n * This package is the default client install path. It re-exports the core\n * engine and Gemini adapter while depending on the Gemini SDK for a one-package\n * setup.\n *\n * @module\n */\n\nexport * from '@gullabs/core'\nexport * from '@gullabs/google'\n\nimport { version } from '../package.json'\n\n/** Library version, sourced from package.json at build time. */\nexport const ANY_LLM_VERSION: string = version\n"]}
1
+ {"version":3,"sources":["../package.json","../src/index.ts"],"names":[],"mappings":";;;;;;AAEE,IAAA,OAAA,GAAW,OAAA;;;ACcN,IAAM,eAAA,GAA0B","file":"index.js","sourcesContent":["{\n \"name\": \"@gullabs/any-llm\",\n \"version\": \"0.6.0\",\n \"description\": \"Batteries-included any-llm client for Gemini: engine, adapter, and Google SDK in one install.\",\n \"type\": \"module\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/gullabs/any-llm.git\",\n \"directory\": \"packages/any-llm\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\",\n \"skills\"\n ],\n \"scripts\": {\n \"build\": \"tsup\"\n },\n \"dependencies\": {\n \"@google/genai\": \"^1.45.0 || ^2\",\n \"@gullabs/core\": \"workspace:*\",\n \"@gullabs/google\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=20.9.0\"\n },\n \"sideEffects\": false,\n \"keywords\": [\n \"llm\",\n \"gemini\",\n \"google-genai\",\n \"ai\",\n \"tokens\",\n \"cost\",\n \"usage\",\n \"observability\",\n \"typescript\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"homepage\": \"https://github.com/gullabs/any-llm/tree/main/packages/any-llm#readme\",\n \"bugs\": \"https://github.com/gullabs/any-llm/issues\"\n}\n","/**\n * @gullabs/any-llm — batteries-included public entrypoint.\n *\n * This package is the default client install path. It re-exports the core\n * engine and Gemini adapter while depending on the Gemini SDK for a one-package\n * setup.\n *\n * @module\n */\n\nexport * from '@gullabs/core'\nexport * from '@gullabs/google'\n\nimport { version } from '../package.json'\n\n/** Library version, sourced from package.json at build time. */\nexport const ANY_LLM_VERSION: string = version\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gullabs/any-llm",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Batteries-included any-llm client for Gemini: engine, adapter, and Google SDK in one install.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -25,8 +25,8 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@google/genai": "^1.45.0 || ^2",
28
- "@gullabs/core": "0.4.3",
29
- "@gullabs/google": "0.5.2"
28
+ "@gullabs/core": "0.5.0",
29
+ "@gullabs/google": "0.6.0"
30
30
  },
31
31
  "engines": {
32
32
  "node": ">=20.9.0"
@@ -9,9 +9,10 @@ description: >-
9
9
  a UsageSink for cost tracking. Also applies whenever the user mentions any-llm, the
10
10
  Gemini adapter, Gemini Flex tier, structured-output validation, or per-call auth for
11
11
  this library. Covers the mandatory per-call `{ auth: { apiKey } }` pattern (there is
12
- no env-var or ambient auth), the caller-owned output-validation contract, and the
13
- reject-don't-map error philosophy — the things a developer used to other LLM SDKs
14
- would otherwise get wrong by default.
12
+ no env-var or ambient auth), the caller-owned output-validation contract, the
13
+ descriptor-owned strict model-config boundary (`configSchema` / `configJsonSchema`),
14
+ and the reject-don't-map error philosophy — the things a developer used to other
15
+ LLM SDKs would otherwise get wrong by default.
15
16
  ---
16
17
 
17
18
  # any-llm
@@ -102,8 +103,36 @@ further `{{...}}`, preventing template injection) and applies to both `system` a
102
103
  `userTemplate`. A missing var is left as the literal `{{var}}` placeholder, not an
103
104
  empty string. `runStructured` also accepts a two-arg form, `(callSite, opts)`, when the
104
105
  template has no vars. Config resolution order everywhere is
105
- `clientDefaults → callSite.config → opts.config` (later wins; objects like `reasoning`
106
- and `providerOptions` merge key-by-key, everything else is last-write-wins).
106
+ `clientDefaults → callSite.config → opts.config`, and the merged config must still pass
107
+ the selected descriptor's strict runtime schema before dispatch.
108
+
109
+ ## Strict model-config boundary
110
+
111
+ Treat model config as descriptor-owned:
112
+
113
+ ```ts
114
+ import { defaultGeminiRegistry } from '@gullabs/core'
115
+
116
+ const descriptor = defaultGeminiRegistry.resolve('gemini-3.5-flash')
117
+ if (!descriptor) throw new Error('unknown model')
118
+
119
+ // UI/forms:
120
+ const formSchema = descriptor.configJsonSchema
121
+
122
+ // Persisted or user-supplied config:
123
+ const parsedConfig = descriptor.configSchema.parse({
124
+ reasoning: { effort: 'medium' },
125
+ serviceTier: 'flex',
126
+ })
127
+ ```
128
+
129
+ Important distinctions:
130
+
131
+ - `descriptor.configSchema` is the runtime boundary for request config.
132
+ - `descriptor.configJsonSchema` is derived from that same schema for form generation.
133
+ - `request.output.jsonSchema` is only the output-format hint for structured responses.
134
+ - `providerOptions.google` is a typed provider-extension lane, not a caller-wins
135
+ override lane for `serviceTier`, sampling, reasoning, or response schema.
107
136
 
108
137
  ## Structured output — auth + validation together
109
138
 
@@ -194,10 +223,10 @@ try {
194
223
  Bad input or config throws `bad_request` (or `invalid_auth`) **before any I/O** —
195
224
  nothing is silently clamped, coerced, or defaulted around a typo. Examples already
196
225
  enforced by the engine/adapter: an unrouteable `model` string, a config value that
197
- fails a model's schema (`validateConfig`), a `reasoning.budgetTokens` set on a model
198
- whose API only supports `reasoning.effort`, duplicate adapter/middleware `id`s, and
199
- grounding (`providerOptions.google.tools` search) combined with `output.jsonSchema` in
200
- the same request (mutually exclusive on Gemini — see `docs/grounded-structured.md`).
226
+ fails the selected descriptor schema, a `reasoning.budgetTokens` set on a model whose
227
+ API only supports `reasoning.effort`, duplicate adapter/middleware `id`s, and a
228
+ grounding + structured-output combination outside the exact documented Gemini support
229
+ set.
201
230
 
202
231
  **Do not add defensive fallback/clamping code around this library.** If a call throws
203
232
  `bad_request`, fix the input — do not catch-and-retry with a "safer" guessed value; the
@@ -213,14 +242,19 @@ config: {
213
242
 
214
243
  `ReasoningEffort` is `'none' | 'low' | 'medium' | 'high'`. Two provider APIs exist
215
244
  under the hood: Gemini 2.5 models take a token `budgetTokens`; Gemini 3.x / Gemma 4
216
- models take a discrete `effort` level (`thinkingLevel`). `EFFORT_BUDGET` (from
217
- `@gullabs/core`) is the shared effort→token mapping (`none: 0, low: 1024, medium: 8192,
218
- high: 24576`) and `resolveReasoning({ model, budgetTokens, registry })` — also exported
219
- from `@gullabs/core` — buckets a raw token budget into the nearest admitted effort
220
- level for a given model, throwing `bad_request` if the model doesn't support reasoning
221
- at all or has no admitted effort at or above the requested bucket. Prefer setting
222
- `reasoning.effort` directly for level-API models rather than a token budget; the
223
- adapter throws `bad_request` if you pass `budgetTokens` to a level-API model.
245
+ models take a discrete `effort` level (`thinkingLevel`).
246
+
247
+ Use the model-native boundary directly:
248
+
249
+ - Gemini 2.5: `reasoning.budgetTokens` or admitted `reasoning.effort`
250
+ - Gemini 3 / Gemma 4: `reasoning.effort`
251
+
252
+ Exact model reminders:
253
+
254
+ - `gemini-3.1-pro-preview` does **not** admit `effort: 'none'`
255
+ - Gemma 4 is binary: only `effort: 'none'` or `effort: 'high'`
256
+ - Omit `serviceTier` for provider-standard; set `flex` explicitly
257
+ - `priority` remains rejected by the library even though Google documents it
224
258
 
225
259
  ## Rate limiting and cost tracking
226
260
 
@@ -246,7 +280,9 @@ adapter throws `bad_request` if you pass `budgetTokens` to a level-API model.
246
280
  the Gemini Developer API (API-key auth) is supported.
247
281
  - Catching a `bad_request` `LlmError` and retrying with a clamped/guessed value instead
248
282
  of fixing the call — the library never silently coerces invalid config.
249
- - Setting `reasoning.budgetTokens` on a `thinkingLevel`-API model (Gemini 3.x / Gemma 4) — use `reasoning.effort` instead; the adapter throws `bad_request` otherwise.
283
+ - Setting `reasoning.budgetTokens` on a `thinkingLevel`-API model (Gemini 3.x / Gemma 4) — use `reasoning.effort` instead; the descriptor schema should reject it.
284
+ - Assuming omitted `serviceTier` still means Flex — it now stays omitted and
285
+ uses provider-default request behavior unless you explicitly opt into `flex`.
250
286
 
251
287
  ## For more detail
252
288