# v0.28.16 Release Notes

> v0.28.15 -> v0.28.16

## Summary

Reshapes the provider layer so construction and model listing share one config path as the router split continues. Improves task resumption so models keep full context while history stays compact, and tightens usage reporting in the TUI.

<details>
<summary>翻譯</summary>

延續 router 拆分，重塑 provider 建構與模型清單共用同一設定路徑。改善任務續跑，讓模型保留完整上下文、歷史保持精簡，並收斂 TUI 用量顯示。

</details>

## ⚠️ Breaking Changes

### `Agent.Execute` removed from the agent interface

Providers no longer implement skill execution. Runtime owns the execution path; agents only implement `Send`.

**Before:**
```go
type Agent interface {
	Name() string
	Send(ctx context.Context, messages []Message, toolDefs []toolTypes.Tool) (*Output, error)
	Execute(ctx context.Context, skill *skill.Skill, userInput string, events chan<- Event, allowAll bool) error
}
```

**After:**
```go
type Agent interface {
	Name() string
	Send(ctx context.Context, messages []Message, toolDefs []toolTypes.Tool) (*Output, error)
}
```

**Migration:**
```go
// Old — provider-side skill execution
agent.Execute(ctx, skill, userInput, events, allowAll)

// New — runtime owns execution; agents only implement Send
// Construct via router.New(...), then call exec.Execute / exec.GetSession
// from the application runtime path.
```

<details>
<summary>翻譯</summary>

`Agent.Execute` 已從介面移除。Provider 不再承載 skill 執行；執行路徑改由 runtime 負責，agent 只實作 `Send`。

</details>

### Provider constructors take `provider.Config`

All provider `New` functions no longer accept model-name varargs or read keychain themselves. Callers pass a unified config struct.

**Before:**
```go
func New(model ...string) (*Agent, error)
// e.g. claude.New("claude@claude-sonnet-4")
```

**After:**
```go
func New(config provider.Config) (*Agent, error)
// provider.Config{Model, APIKey, Token, BaseURL, AccountID, GatewayID}
```

**Migration:**
```go
// Old
agent, err := claude.New("claude@claude-sonnet-4")

// New
agent, err := claude.New(provider.Config{
	Model:  "claude-sonnet-4",
	APIKey: apiKey,
})
// Prefer router.New(router.Config{Name: "claude@claude-sonnet-4", APIKey: apiKey})
```

<details>
<summary>翻譯</summary>

所有 provider 建構子改收統一的 `provider.Config`，不再自行讀 keychain 或接受 model 變參。建議改走 `router.New`。

</details>

### `RateLimit` moved to `agentTypes`

The 429 rate-limit error type left the exec package so oauth and providers can share one definition.

**Before:**
```go
// package exec
type RateLimit struct {
	Agent    string
	ResetsAt int64
	Body     string
}
```

**After:**
```go
// package agentTypes
type RateLimit struct {
	Agent    string
	ResetsAt int64
	Body     string
}
```

**Migration:**
```go
// Old
var rl *exec.RateLimit
errors.As(err, &rl)

// New
var rl *agentTypes.RateLimit
errors.As(err, &rl)
```

<details>
<summary>翻譯</summary>

`RateLimit` 從 `exec` 搬到 `agentTypes`，oauth 與 provider 共用同一型別。請更新 import 與型別參照。

</details>

### Model listing APIs take `provider.Config`

Per-provider model listing is no longer zero-arg. Callers pass credentials through the shared config.

**Before:**
```go
// typical prior shape (package-local credentials)
ids, err := claude.Models(ctx)
```

**After:**
```go
ids, err := claude.Models(ctx, provider.Config{APIKey: apiKey})
```

**Migration:**
```go
// Old
ids, err := claude.Models(ctx)

// New
ids, err := claude.Models(ctx, provider.Config{APIKey: apiKey})
// Token / AccountID / GatewayID as required by the provider
```

<details>
<summary>翻譯</summary>

各 provider 的模型清單 API 改收 `provider.Config`，需由呼叫端傳入憑證，不再假設 package 內部 keychain 狀態。

</details>

### Image and STT tools relocated under `internal/tools`

`generate_image` and speech-to-text registration moved out of provider packages into first-class tool packages.

**Before:**
```text
internal/agents/provider/openaiCodex/image2/
internal/agents/provider/gemini/stt/
```

**After:**
```text
internal/tools/image2/
internal/tools/stt/
```

**Migration:**
```go
// Old
import image2 "github.com/pardnchiu/agenvoy/internal/agents/provider/openaiCodex/image2"
import stt "github.com/pardnchiu/agenvoy/internal/agents/provider/gemini/stt"

// New
import "github.com/pardnchiu/agenvoy/internal/tools/image2"
import "github.com/pardnchiu/agenvoy/internal/tools/stt"

// Registration remains image2.Register() / stt.Register() at app bootstrap.
```

<details>
<summary>翻譯</summary>

影像生成與語音轉文字工具從 provider 套件搬到 `internal/tools`。請更新 import 路徑；註冊方式仍為 bootstrap 時呼叫 `Register()`。

</details>

## Changes

### BREAKING
- Remove `Agent.Execute` from every provider and leave only `Send` on the agent interface (@pardnchiu) [bf866457]
- Move rate-limit errors into shared agent types and relocate image generation under tools (@pardnchiu) [2e2ccd66]
- Unify provider construction on a shared config and relocate speech-to-text under tools (@pardnchiu) [0939f1c0]
- Require provider config for model listing as the router split continues (@pardnchiu) [4175043f]

<details>
<summary>翻譯</summary>

- 從所有 provider 移除 `Agent.Execute`，介面只保留 `Send`
- 將 rate-limit 錯誤移入共用 agent types，並把影像生成工具遷到 tools
- 統一以共用 config 建構 provider，並把語音轉文字工具遷到 tools
- 模型清單 API 改需 provider config，延續 router 拆分

</details>

### FEAT
- Improve task resumption so models keep full context while history stays compact, and tighten usage reporting (@pardnchiu) [adc10394]

<details>
<summary>翻譯</summary>

- 改善任務續跑：模型保留完整上下文、歷史保持精簡，並收斂用量回報

</details>

## Scope

- `internal/agents/types/` — BREAKING (`agent.go`, `rateLimit.go`)
- `internal/agents/provider/` — BREAKING (multiple files)
- `internal/agents/router/` — BREAKING (`router.go`)
- `internal/agents/keychain/` — ADD (`keychain.go`)
- `internal/agents/oauth/` — UPDATE (`codex`, `copilot`, `grok`)
- `internal/agents/exec/` — FEAT, UPDATE (`execute.go`, `getSession.go`, `run.go`, `cooldown.go`)
- `internal/tools/image2/` — BREAKING (relocated)
- `internal/tools/stt/` — BREAKING (relocated)
- `internal/tools/interactive/` — FEAT (`askUser.go`)
- `internal/runtime/tui/` — FEAT (multiple files)
- `internal/runtime/telegram/` — FEAT (`resume.go`, `session.go`)
- `internal/runtime/discord/` — FEAT (`resume.go`, `session.go`)
- `internal/runtime/routes/handler/` — FEAT (`pending.go`)
- `internal/session/usage/` — FEAT (`summary.go`)
- `cmd/app/` — BREAKING (`buildAgentRegistry.go`, `newTUI.go`, `cmdDeamon.go`)

***

Generated by [SKILL](https://github.com/pardnchiu/skill-version-generate)
