@combycode/llm-sdk 1.5.0 → 1.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/CHANGELOG.md +102 -0
- package/dist/index.browser.js +2806 -921
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2806 -921
- package/dist/llm/client-internal.d.ts +11 -0
- package/dist/llm/output-errors.d.ts +24 -0
- package/dist/llm/providers/anthropic/messages.d.ts +5 -2
- package/dist/llm/providers/builtin-tools.d.ts +4 -1
- package/dist/llm/providers/google/interactions.d.ts +11 -1
- package/dist/llm/providers/xai/tiers.d.ts +12 -0
- package/dist/llm/types/options.d.ts +10 -0
- package/dist/llm/types/request.d.ts +6 -0
- package/dist/llm/types/response.d.ts +11 -1
- package/dist/llm/types/stream.d.ts +7 -1
- package/dist/llm/types/tools.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,107 @@ All notable changes to `@combycode/llm-sdk` are documented here. The format foll
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.6.0] - 2026-07-11
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **Typed structured-output failure + opt-in repair.** Structured output that can't be parsed now throws
|
|
13
|
+
a typed `InvalidFinalOutputError` (extends `AgentRunError`, carries `reason: 'invalid_final_output'` and
|
|
14
|
+
the model's `rawText`) instead of a bare `SyntaxError`, so callers can `instanceof`/inspect/retry.
|
|
15
|
+
`structuredComplete` gains an opt-in `structured.repairAttempts` (default 0): on a parse failure it
|
|
16
|
+
re-prompts with the error up to N times before throwing. Exports `AgentRunError`,
|
|
17
|
+
`InvalidFinalOutputError`. (`max_steps` / `model_refusal` stay returned results, differentiated by
|
|
18
|
+
`finishReason` / `AgentRunReport.reason`; run-error handler hooks can layer on later.)
|
|
19
|
+
- **`user_profile_id` + Interactions `cached_content`.** Anthropic forwards `providerOptions.userProfileId`
|
|
20
|
+
to the `anthropic-user-profile-id` header; Google Interactions maps `providerOptions.cachedContent` to
|
|
21
|
+
its `cached_content` resource.
|
|
22
|
+
- **Sampling penalties.** `presencePenalty` / `frequencyPenalty` ([-2, 2]) on `complete()` / `stream()`
|
|
23
|
+
(and `NormalizedRequest`), mapped to the providers that accept them — OpenAI/xAI **chat-completions**
|
|
24
|
+
(`presence_penalty` / `frequency_penalty`), OpenRouter (inherited), Google **generateContent**
|
|
25
|
+
(`generationConfig.presencePenalty` / `frequencyPenalty`) and **Interactions** (snake_case). Ignored by
|
|
26
|
+
OpenAI/xAI **Responses** and Anthropic, which don't accept them (verified against the SDK sources — the
|
|
27
|
+
Responses API has no penalty fields). Verified live on OpenAI, Google, and xAI.
|
|
28
|
+
- **Unified `web_fetch` hosted tool.** New `{ type: 'web_fetch' }` builtin that reads a
|
|
29
|
+
user-provided URL, mapped to Anthropic's `web_fetch_20260318` (GA; `params` like `allowed_domains`
|
|
30
|
+
/ `blocked_domains` / `citations` / `max_content_tokens` / `max_uses` forwarded verbatim, with
|
|
31
|
+
`allowed_callers: ['direct']` defaulted so it works on chat models) and Google's `urlContext` tool.
|
|
32
|
+
The fetched URL surfaces on `response.builtinToolCalls` (`{ tool: 'web_fetch', url }`) and the
|
|
33
|
+
streamed `builtin_tool_start` / `builtin_tool_end` events, normalized across both providers.
|
|
34
|
+
`capabilities.builtinTools` / `catalog.supportsBuiltinTool()` / `select('web_fetch')` report it on
|
|
35
|
+
Anthropic + Google (OpenAI's `web_search` already opens pages; xAI / OpenRouter expose no fetch
|
|
36
|
+
tool). Verified live on Anthropic and Google.
|
|
37
|
+
- **Builtin-tool call payloads.** `BuiltinToolCall` (and the `builtin_tool_end` stream event) now
|
|
38
|
+
carry what the tool ran: `code` + `output` (stdout) for `code_interpreter`, and `query` (search
|
|
39
|
+
step) or `url` (page-open step) for `web_search` — normalized across every provider (OpenAI/xAI
|
|
40
|
+
`code_interpreter_call.code` + `web_search_call.action` `query`/`queries[]`/`url`, Anthropic
|
|
41
|
+
`server_tool_use.input` streamed via `input_json_delta` and correlated to its `*_tool_result`
|
|
42
|
+
stdout, Google `executableCode`/`codeExecutionResult` + grounding `webSearchQueries`). A single
|
|
43
|
+
OpenAI web search is a multi-step agent: `search` actions carry a query, `open_page`/`find`
|
|
44
|
+
actions carry the URL they read. Available on both `complete()` and streamed responses; verified
|
|
45
|
+
live on all four providers.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- **Anthropic web-search bumped to `web_search_20260318`** (from `web_search_20250305`) and now forwards
|
|
49
|
+
the unified `BuiltinTool.params` verbatim — `allowed_domains`, `blocked_domains`, `user_location`,
|
|
50
|
+
`response_inclusion`, `max_uses` (previously all silently dropped). The new version defaults to
|
|
51
|
+
*programmatic* tool calling (via code execution), which chat models like haiku reject, so the adapter
|
|
52
|
+
sends `allowed_callers: ['direct']` by default to preserve the classic direct-call behaviour; callers
|
|
53
|
+
override any default through `params`. Live-verified across all providers (scenario 27, 5/5).
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
- **xAI `service_tier` maps to xAI's own enum.** The xAI adapter inherited OpenAI's tier map and could
|
|
57
|
+
emit `auto` / `flex` / `scale`, which xAI's API rejects (its `ServiceTier` is `default` | `priority`
|
|
58
|
+
only). It now remaps from the unified tier — `standard` → `default`, `priority` → `priority`, and any
|
|
59
|
+
value xAI can't honor is omitted (the server picks its default) rather than 400'ing. Live-verified:
|
|
60
|
+
`priority` sent and billed back (`usage.serviceTier`/`pricingTier`), `flex` no longer errors.
|
|
61
|
+
- **Agent loop no longer swallows failed runs into empty text.** `AgentLoop.complete()` and
|
|
62
|
+
`.stream()` caught any mid-run LLM error, set `finishReason:'error'`, and returned an empty
|
|
63
|
+
`CompletionResponse` (or ended the stream) with the error message dropped — so a tool-using
|
|
64
|
+
`complete()` / `delegate()` / `handoff()` returned `""` on an auth failure, rate limit, context
|
|
65
|
+
overflow, etc., while the same call *without* tools threw. Both now **re-throw** the original error
|
|
66
|
+
(preserving `LLMError` kind/status) after finalizing metrics/hooks, matching the no-tools path and
|
|
67
|
+
the raw client stream. `AgentLoop.run()` is unchanged — it still returns an `AgentRunReport` with
|
|
68
|
+
`reason:'error'` + `error` for callers that want partial results. Live-verified (bad key → thrown
|
|
69
|
+
`auth` error, not empty text).
|
|
70
|
+
- **Agent loop now continues stateful turns server-side.** After a tool call the loop stamped its
|
|
71
|
+
assistant turn without provenance, so multi-turn runs on a stateful API always resent the full
|
|
72
|
+
transcript. On Google Interactions that transcript replay is *rejected* (the API requires resuming
|
|
73
|
+
by `previous_interaction_id`), which surfaced as an **empty final answer** on agentic tool use. The
|
|
74
|
+
loop now stamps `id` / `createdAt` / `origin.serverStateId` (via the shared `buildAssistantMessage`),
|
|
75
|
+
so the server-state brain continues by id and sends only the new turn — gated, as before, by catalog
|
|
76
|
+
support, the retention TTL (openai/xai 30d, google 72h), and model binding. Live-verified: Interactions
|
|
77
|
+
agentic round-trip now answers; OpenAI Responses / Anthropic tool loops unchanged.
|
|
78
|
+
- **Google Interactions streaming (opt-in `api: 'interactions'`) brought current with the 2.10 wire.**
|
|
79
|
+
The regenerated Interactions client replaced the old `content.delta` / `interaction.complete` events
|
|
80
|
+
with a step machine — `step.start` / `step.delta` / `step.stop`, `interaction.created` /
|
|
81
|
+
`interaction.completed` / `interaction.status_update` — so the previous parser produced no output.
|
|
82
|
+
The parser now reads `step.delta` payloads (`text`, `thought_summary` → thinking, `arguments_delta`),
|
|
83
|
+
opens/attaches/closes a function call across `step.start` → `arguments_delta` → `step.stop` (the
|
|
84
|
+
`arguments_delta` carries no id, so a per-stream parser correlates it), and finishes on
|
|
85
|
+
`interaction.completed` / `interaction.failed` with usage from `interaction.usage`. Live-verified
|
|
86
|
+
against the 2.10 API (streamed text, tool calls, usage). The default Google path (`generateContent`)
|
|
87
|
+
is unaffected.
|
|
88
|
+
- **OpenAI web-search query precedence.** OpenAI deprecated the singular `web_search_call.action.query`
|
|
89
|
+
in favour of `action.queries[]`; the Responses adapter now prefers the array and falls back to the
|
|
90
|
+
scalar, so `BuiltinToolCall.query` stays populated on the new wire.
|
|
91
|
+
- **Duplicate OpenAI code-execution files.** When code calls `plt.show()` *and* saves the figure,
|
|
92
|
+
OpenAI emits an extra auto-display container file alongside the saved one — surfacing the same
|
|
93
|
+
chart twice on `response.files`. The Responses adapter now drops the auto-display artifact (an
|
|
94
|
+
image citation named after its own file id, with a zero-width span) when the same image was also
|
|
95
|
+
saved, matching ChatGPT's own UI. A display-only run keeps its sole figure; distinct saved files
|
|
96
|
+
are never collapsed. Investigated across providers: only OpenAI has this pattern (Anthropic/xAI
|
|
97
|
+
return only saved files; Google returns one artifact per output) — so the fix is scoped to the
|
|
98
|
+
OpenAI Responses adapter.
|
|
99
|
+
|
|
100
|
+
## [1.5.1] - 2026-07-06
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
- `retrieveFile` / `streamFile` now send Anthropic's `anthropic-dangerous-direct-browser-access:
|
|
104
|
+
true` header in the browser, for consistency with the completion adapter. **Note:** this does
|
|
105
|
+
NOT make Anthropic hosted-tool files downloadable from a browser — Anthropic's Files API
|
|
106
|
+
(`GET /v1/files/{id}/content`) does not return CORS headers (unlike `/v1/messages`), so file
|
|
107
|
+
retrieval for Anthropic is **server-side only** (verified against the API + the official docs).
|
|
108
|
+
OpenAI works in-browser; Google and xAI return files inline (no fetch), so they work too.
|
|
109
|
+
|
|
9
110
|
## [1.5.0] - 2026-07-06
|
|
10
111
|
|
|
11
112
|
### Added
|
|
@@ -137,6 +238,7 @@ First public release.
|
|
|
137
238
|
- Service tiers end to end (request → bill → cost).
|
|
138
239
|
- Cross-environment: runs on Node, Bun, and the browser. ESM, zero runtime deps.
|
|
139
240
|
|
|
241
|
+
[1.6.0]: https://github.com/combycode/llm-sdk-ts/releases/tag/v1.6.0
|
|
140
242
|
[1.2.0]: https://github.com/combycode/llm-sdk-ts/releases/tag/v1.2.0
|
|
141
243
|
[1.1.0]: https://github.com/combycode/llm-sdk-ts/releases/tag/v1.1.0
|
|
142
244
|
[1.0.0]: https://github.com/combycode/llm-sdk-ts/releases/tag/v1.0.0
|