Commit log

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

a3b8a69 fix(openrouter): preserve anthropic reasoning signature in streaming

Click to expand commit body
Anthropic sends the reasoning signature chunk after tool_calls have
started. The streaming hook was ending reasoning prematurely on the
first tool_call chunk, so the late-arriving signature was lost. Track
the reasoning format and defer ending for anthropic streams until the
signature arrives. Also fix the agent stream assembler to not overwrite
provider metadata with nil on reasoning deltas.

💘 Generated with Crush

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

Andrey Nering created

152acfe fix: guard against nil EncryptedContent dereference in reasoning details

Click to expand commit body
Reasoning metadata can exist without encrypted content, causing a nil
pointer panic when building prompt messages for openrouter and vercel.

💘 Generated with Crush

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

Andrey Nering created

50a1116 fix: improve default user-agent string

Click to expand commit body
This change to be better follow the convention:

* App name should not have spaces: `Charm Fantasy` -> `Charm-Fantasy`.
* Add comment `()` with app site.

Andrey Nering created

e8560e6 fix(openai): use noDefaultUserAgent in all responses API calls

Click to expand commit body
💘 Generated with Crush

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

Christian Rocha created

522e026 fix(openai): propagate noDefaultUserAgent to responsesLanguageModel

Click to expand commit body
💘 Generated with Crush

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

Christian Rocha created

2e29858 fix(openrouter): avoid brittle User-Agent assertion

Click to expand commit body
💘 Generated with Crush

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

Christian Rocha created

182ba5f docs(openai): correct grammar in comment

Click to expand commit body
💘 Generated with Crush

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

Christian Rocha created

96f0454 fix(openai): don't mutate shared languageModelOptions

Click to expand commit body
💘 Generated with Crush

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

Christian Rocha created

7dc3888 fix(openrouter): don't set User-Agent

Click to expand commit body
OpenRouter rejects API calls using a custom User Agent. This workaround
skips OpenRouter when setting a user agent.

Note that we've added two new methods accordingly, as OpenRouter uses
the openai package:

openai.WithSkipUserAgent()
openai.WithLanguageModelSkipUserAgent()

Christian Rocha created

04950be v0.12.1

Andrey Nering created

5d76d7d chore(examples): go mod tidy

Andrey Nering created

d9de5db fix(errors): improve check for when to retry requests (#164)

Click to expand commit body
* Follow OpenAI's Go SDK.
* Check status code >= 500.
* Check `x-should-retry` header.

Co-authored-by: yuguorui <yuguorui@pku.edu.cn>

Andrey Nering and yuguorui created

b137f01 chore(deps): bump the all group across 1 directory with 4 updates (#162)

Click to expand commit body
Bumps the all group with 4 updates in the / directory: [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), [golang.org/x/oauth2](https://github.com/golang/oauth2) and [google.golang.org/genai](https://github.com/googleapis/go-genai).


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

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

Updates `golang.org/x/oauth2` from 0.35.0 to 0.36.0
- [Commits](https://github.com/golang/oauth2/compare/v0.35.0...v0.36.0)

Updates `google.golang.org/genai` from 1.48.0 to 1.49.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.48.0...v1.49.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.41.3
  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.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: golang.org/x/oauth2
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: google.golang.org/genai
  dependency-version: 1.49.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

13ad470 ci(dependabot): update kronk in a separate group

Andrey Nering created

ae2e22e ci: fix govulncheck by updating go version (#161)

Andrey Nering created

422f954 v0.12.0

Andrey Nering created

1b0027b feat: configurable user-agent (#152)

Click to expand commit body
Note that the user agent defaults to Charm Fantasy/<version>, which
means we need to maintain a const for the version number.

Christian Rocha created

0806f24 chore(deps): go mod tidy examples (#159)

Christian Rocha created

fb3643d v0.11.1

Andrey Nering created

4747a08 chore: add support for gpt 5.4 (#158)

Andrey Nering created

0a0ed20 chore(deps): bump the all group with 3 updates (#155)

Click to expand commit body
Bumps the all group with 3 updates: [github.com/ardanlabs/kronk](https://github.com/ardanlabs/kronk), [github.com/aws/smithy-go](https://github.com/aws/smithy-go) and [github.com/kaptinlin/jsonschema](https://github.com/kaptinlin/jsonschema).


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

Updates `github.com/aws/smithy-go` from 1.24.1 to 1.24.2
- [Release notes](https://github.com/aws/smithy-go/releases)
- [Changelog](https://github.com/aws/smithy-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws/smithy-go/compare/v1.24.1...v1.24.2)

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

---
updated-dependencies:
- dependency-name: github.com/ardanlabs/kronk
  dependency-version: 1.20.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: github.com/aws/smithy-go
  dependency-version: 1.24.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: github.com/kaptinlin/jsonschema
  dependency-version: 0.7.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  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