Commit log

99e504c v0.17.0

Andrey Nering created

46820ff chore(examples): go mod tidy

Andrey Nering created

0cab8bf feat: anthropic computer use (#185)

Hugo Dutka created

bdfda5e chore(deps): bump github.com/ardanlabs/kronk in the kronk group (#184)

Click to expand commit body
Bumps the kronk group with 1 update: [github.com/ardanlabs/kronk](https://github.com/ardanlabs/kronk).


Updates `github.com/ardanlabs/kronk` from 1.21.3 to 1.21.4
- [Release notes](https://github.com/ardanlabs/kronk/releases)
- [Commits](https://github.com/ardanlabs/kronk/compare/v1.21.3...v1.21.4)

---
updated-dependencies:
- dependency-name: github.com/ardanlabs/kronk
  dependency-version: 1.21.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: kronk
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

dependabot[bot] and dependabot[bot] created

eec5a32 chore(deps): bump the all group with 2 updates (#183)

Click to expand commit body
Bumps the all group with 2 updates: [github.com/kaptinlin/jsonschema](https://github.com/kaptinlin/jsonschema) and [google.golang.org/genai](https://github.com/googleapis/go-genai).


Updates `github.com/kaptinlin/jsonschema` from 0.7.5 to 0.7.6
- [Commits](https://github.com/kaptinlin/jsonschema/compare/v0.7.5...v0.7.6)

Updates `google.golang.org/genai` from 1.50.0 to 1.51.0
- [Release notes](https://github.com/googleapis/go-genai/releases)
- [Changelog](https://github.com/googleapis/go-genai/blob/main/CHANGELOG.md)
- [Commits](https://github.com/googleapis/go-genai/compare/v1.50.0...v1.51.0)

---
updated-dependencies:
- dependency-name: github.com/kaptinlin/jsonschema
  dependency-version: 0.7.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: google.golang.org/genai
  dependency-version: 1.51.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

dependabot[bot] and dependabot[bot] created

ca0e707 v0.16.0

Andrey Nering created

a5bee40 fix(openai): relax tool call validation for ollama compatibility (#113)

Click to expand commit body
Co-authored-by: Andrey Nering <andreynering@users.noreply.github.com>

Gustave and Andrey Nering created

238e34d fix: address tool calls with empty arguments in copilot (#156)

Click to expand commit body
Co-authored-by: Andrey Nering <andreynering@users.noreply.github.com>

Martin and Andrey Nering created

aa7e82f fix(bedrock): don't default baseURL to anthropic API when using bedrock

Click to expand commit body
When useBedrock is true, the DefaultURL ("https://api.anthropic.com") was
being set on providerOptions.baseURL in New(). This caused LanguageModel()
to append option.WithBaseURL("https://api.anthropic.com") after
bedrock.WithConfig had already set the correct bedrock-runtime URL,
overwriting it.

Only set the default base URL for non-bedrock providers. Bedrock gets its
URL from bedrock.WithConfig() in the SDK.

🐙 Generated with Crush

Assisted-by: AWS Claude Opus 4.6 via Crush <crush@charm.land>

Aleks Clark created

8924b01 fix(bedrock): apply base URL override after bedrock.WithConfig

Click to expand commit body
bedrock.WithConfig internally calls option.WithBaseURL with the default
regional endpoint, clobbering any user-provided base_url. Move the
custom base URL append to after the bedrock config block so last-write
wins.

🐨 Generated with Crush

Assisted-by: AWS Claude Opus 4.6 via Crush <crush@charm.land>

Aleks Clark created

277f9fb feat(bedrock): add WithBaseURL option

Click to expand commit body
Allows overriding the default Bedrock endpoint URL, enabling use with
custom or proxy endpoints.

🐙 Generated with Crush

Assisted-by: AWS Claude Opus 4.6 via Crush <crush@charm.land>

Aleks Clark created

236fedf fix(providertests/testdata): update summary thinking fixtures

Michael Suchacz created

ee77281 fix(providers/openai): skip ephemeral replay items

Michael Suchacz created

57940a9 v0.15.1

Andrey Nering created

5e4a443 test: re-record openrouter fixtures

Andrey Nering created

c3f0da5 test(openrouter): simplify list of providers and models to test

Click to expand commit body
Make it shorter (one per major provider) and favor smaller models.

Andrey Nering created

b00cf24 chore: remove unused test function

Andrey Nering created

43df1e4 chore: revert change to skip user-agent for openrouter

Andrey Nering created

dff62fa fix(openai): skip reasoning items in Responses API replay (#181)

Click to expand commit body
When Store is enabled, replaying reasoning items (OfReasoning) in
the Responses API input causes a validation error:

  Item 'rs_xxx' of type 'reasoning' was provided without its
  required following item.

The API stores reasoning server-side and cannot pair a reconstructed
reasoning item with the output item that originally followed it.
The fix skips reasoning parts during replay, letting the conversation
continue with visible assistant content (text / tool calls).

Kyle Carberry created

2556dbc test: add integration tests for avian

Andrey Nering created

6bb474f fix: migrate the openai sdk to our internal fork

Click to expand commit body
The OpenAI SDK has a bug on dealing with SSE events. This was affected
OpenRouter, but we made a workaround for it. See:

* https://github.com/charmbracelet/fantasy/pull/166
* https://github.com/charmbracelet/fantasy/pull/169

We made a fix for the SDK, but it wasn't merged yet:

* https://github.com/openai/openai-go/pull/621

In the meantime, an user reported that Avian has the same issue, but it's
impossible for us to workaround it. Because of this, we had to fork the
SDK. We're pinning the `fantasy` branch from our fork:

* https://github.com/charmbracelet/openai-go/tree/fantasy

Andrey Nering created

d120cc3 v0.15.0

Andrey Nering created

f910b4c feat(agent): allow empty prompt when messages exist (#179)

Click to expand commit body
Allow empty prompts when there are messages and no files to attach.
The last message must be a user or tool message - this ensures the
conversation state is valid for the LLM to respond.

This addresses use cases where:
- Generating from an existing conversation
- Tool results were just returned and we want the LLM to respond

Validation:
- Error if empty prompt with no messages
- Error if empty prompt with files (files need a user message)
- Error if last message is assistant (nothing to respond to)
- Allow if last message is user or tool

Closes #54
Closes #59
Closes #103

Co-authored-by: Arun Barua <arun.barua@onit.com>
Co-authored-by: Ruslan Mayer <r.stupa@ya.ru>

Andrey Nering , Arun Barua , and Ruslan Mayer created

09d2b74 feat: support `text/*` files (#100)

Carlos Alexandro Becker created

d749d13 fix(anthropic): ToolChoiceNone should send tool_choice:{type:"none"} to API (#178)

Click to expand commit body
The Anthropic provider's toTools function was returning nil for
anthropicToolChoice when ToolChoiceNone was set, which meant
tool_choice was never included in the API request. The API defaults
to "auto", so the model could still make tool calls.

Now properly constructs ToolChoiceUnionParam with OfNone set using
anthropic.NewToolChoiceNoneParam().

Also adds test coverage for ToolChoiceNone.

* Closes #177

💘 Generated with Crush

Assisted-by: Kimi K2.5 via Crush <crush@charm.land>

Andrey Nering created

1568c97 fix(anthropic): anthropic with vertex works with service account json keys (#157)

Click to expand commit body
Signed-off-by: Calum Murray <cmurray@redhat.com>

Calum Murray created

6b63c3c v0.14.0

Andrey Nering created

22c3e9a fix(openai): subtract cached tokens from input tokens to avoid double counting (#176)

Click to expand commit body
OpenAI's API reports prompt_tokens/input_tokens INCLUDING cached tokens,
while also separately reporting cached_tokens in prompt_tokens_details.
This caused double-counting when users summed InputTokens + CacheReadTokens.

For example, if OpenAI reports:
  - prompt_tokens: 1000 (includes 900 cached)
  - cached_tokens: 900

Before this fix, fantasy reported:
  - InputTokens: 1000
  - CacheReadTokens: 900

After this fix, fantasy reports:
  - InputTokens: 100 (non-cached only)
  - CacheReadTokens: 900

This matches the behavior of Vercel AI SDK and prevents billing
miscalculations when pricing input tokens and cache read tokens separately.

See: https://platform.openai.com/docs/guides/prompt-caching#requirements

💘 Generated with Crush

Assisted-by: Kimi K2.5 via Crush <crush@charm.land>

Andrey Nering created

0c8663f feat(openai): add responses api `store`, `previous_response_id`, and `response.id` support (#175)

Click to expand commit body
Co-authored-by: Christian Rocha <christian@rocha.is>

Michael Suchacz and Christian Rocha created

30ed858 v0.13.1

Andrey Nering created

c684b60 chore: add support for gpt 5.4 mini and nano (#174)

Andrey Nering created

ad51627 fix: address kronk api change

Andrey Nering created

4ae1f35 chore(deps): bump github.com/ardanlabs/kronk in the kronk group

Click to expand commit body
Bumps the kronk group with 1 update: [github.com/ardanlabs/kronk](https://github.com/ardanlabs/kronk).


Updates `github.com/ardanlabs/kronk` from 1.20.8 to 1.21.3
- [Release notes](https://github.com/ardanlabs/kronk/releases)
- [Commits](https://github.com/ardanlabs/kronk/compare/v1.20.8...v1.21.3)

---
updated-dependencies:
- dependency-name: github.com/ardanlabs/kronk
  dependency-version: 1.21.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: kronk
...

Signed-off-by: dependabot[bot] <support@github.com>

dependabot[bot] created

86872ba v0.13.0

Andrey Nering created

f20a77d docs(readme): remove experimental note + provider tools is now supported

Andrey Nering created

9cf02ad chore: delete duplicated example

Click to expand commit body
This is currently already covered by `web-search` example.

Andrey Nering created

6462ab9 feat(openai): add web search tool support for Responses API (#173)

Click to expand commit body
Add OpenAI web search as a provider-defined tool, mirroring the
Anthropic web search implementation pattern.

New files:
- providers/openai/web_search.go: WebSearchTool() helper with
  SearchContextSize, AllowedDomains, and UserLocation options.
- examples/openai-web-search/main.go: Example using the agent
  pattern with web search.

Changes to existing files:
- responses_options.go: WebSearchCallMetadata, WebSearchAction,
  and WebSearchSource types registered for JSON round-tripping.
- responses_language_model.go:
  - toResponsesTools(): Route ProviderDefinedTool web_search to
    the OpenAI SDK WebSearchToolParam.
  - Generate(): Emit ToolCallContent + ToolResultContent pair for
    web_search_call output items. Source citations come from
    url_citation annotations on message text.
  - Stream(): Emit ToolInputStart/ToolInputEnd/ToolCall/ToolResult
    lifecycle events for web_search_call items.
  - toResponsesPrompt(): Round-trip provider-executed tool calls
    via item_reference; skip SourceContent and provider-executed
    ToolResultPart (already handled by the reference).
- providertests/provider_registry_test.go: Add metadata test case.

Kyle Carberry created

522a4f8 docs(agents): minor AGENTS.md updates

Christian Rocha created

720c765 Merge pull request #163 from kylecarbs/feat/anthropic-web-search

Click to expand commit body
Add support for the Anthropic web search tool

Christian Rocha created

85e0422 fix(lint): guard against overflow

Christian Rocha created

df8bcd9 chore(deps): bump the all group with 4 updates (#171)

Click to expand commit body
Bumps the all group with 4 updates: [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2), [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2), [github.com/openai/openai-go/v3](https://github.com/openai/openai-go) and [google.golang.org/genai](https://github.com/googleapis/go-genai).


Updates `github.com/aws/aws-sdk-go-v2` from 1.41.3 to 1.41.4
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.41.3...v1.41.4)

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.32.11 to 1.32.12
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.32.11...config/v1.32.12)

Updates `github.com/openai/openai-go/v3` from 3.26.0 to 3.28.0
- [Release notes](https://github.com/openai/openai-go/releases)
- [Changelog](https://github.com/openai/openai-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/openai/openai-go/compare/v3.26.0...v3.28.0)

Updates `google.golang.org/genai` from 1.49.0 to 1.50.0
- [Release notes](https://github.com/googleapis/go-genai/releases)
- [Changelog](https://github.com/googleapis/go-genai/blob/main/CHANGELOG.md)
- [Commits](https://github.com/googleapis/go-genai/compare/v1.49.0...v1.50.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.41.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: github.com/aws/aws-sdk-go-v2/config
  dependency-version: 1.32.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: github.com/openai/openai-go/v3
  dependency-version: 3.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: google.golang.org/genai
  dependency-version: 1.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

dependabot[bot] and dependabot[bot] created

eaa111e chore(anthroipic): harden web_search coercion for json round-trips

Click to expand commit body
This guards against cases when web_search options could be silently
dropped when tool args pass through generic/JSON-shaped data, so domain
filters, max uses, and user location reliably reach Anthropic.

Christian Rocha created

0320b54 chore(examples): go mod tidy

Christian Rocha created

2460fd0 fix(agent): make per-step tool selection apply to all tool types

Christian Rocha created

ffc8408 v0.12.3

Andrey Nering created

50d95df chore: update openai sdk to v3 (#168)

Andrey Nering created

caf105e test: re-record almost all fixtures (#167)

Andrey Nering created

38eb77b feat: add Anthropic web search tool support (server_tool_use + web_search_tool_result)

Click to expand commit body
- Handle ProviderDefinedTool with ID "web_search" in toTools(), mapping to
  anthropic.WebSearchTool20250305Param with optional allowed/blocked domains
- Parse "server_tool_use" blocks in Generate() and Stream(), producing
  ToolCallContent with ProviderExecuted=true
- Parse "web_search_tool_result" blocks, extracting SourceContent for each
  search result and a ToolResultContent summary
- Stream server_tool_use via ToolInputStart/ToolInputEnd/ToolCall events
- Stream web_search_tool_result via Source events for each result item
- Skip provider-executed tool results and source content when building
  Anthropic prompts (toPrompt) to avoid sending unrecognized block types
- Add ProviderExecuted field to ToolResultPart with JSON marshal/unmarshal
- Propagate ProviderExecuted from ToolResultContent to ToolResultPart in
  agent's toResponseMessages()

Kyle Carberry created

fa02069 v0.12.2

Andrey Nering created

7ebd9b5 test: re-record all openrouter fixtures

Andrey Nering created