You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(think): bundle workers-ai-provider and accept model id strings (#1832)
Make the common model-config case zero-boilerplate: `getModel()` (and the
`beforeTurn`/`beforeStep` per-turn/per-step overrides) now accept a model id
string resolved through a built-in `workers-ai-provider` instance, so users no
longer install/import/wire the provider themselves.
- getModel() returns `ThinkModel` (new exported alias for
`LanguageModel | ThinkModelId`); `ThinkModelId` gives `@cf/...` autocomplete
while accepting any gateway slug string.
- Bundle `workers-ai-provider` + `@ai-sdk/openai`/`@ai-sdk/anthropic` wire
plugins as deps; `@cf/...` ids hit Workers AI (with sessionAffinity),
other `<provider>/<model>` slugs route through AI Gateway.
- Add `getAIBinding()` (default `env.AI`) and public `resolveModel(model?)`
for side inference calls (summarization/compaction).
- Widen `TurnConfig.model` and `StepConfig.model` to `ThinkModel`; resolve
string overrides before handing the step to the AI SDK.
- Scaffolder + all starters + non-starter examples + docs use string models;
drop `workers-ai-provider` from their deps and from THIRD_PARTY_DEPENDENCIES.
Co-authored-by: Sunil Pai <18808+threepointone@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
`getModel()` now accepts a model id string, resolved through a built-in `workers-ai-provider` instance — no separate provider package to install, import, or wire up for the common case.
6
+
7
+
Think now depends on `workers-ai-provider` (plus the `@ai-sdk/openai` and `@ai-sdk/anthropic` wire-format plugins) directly. When `getModel()` returns a string, Think resolves it off your `AI` binding:
8
+
9
+
- A `@cf/...` id hits Workers AI directly (with `sessionAffinity` wired in automatically for prefix-cache hits).
10
+
- Any other `"<provider>/<model>"` slug — e.g. `"openai/gpt-5.5"`, `"anthropic/claude-sonnet-4-5"`, `"google/gemini-2.5-pro"`, `"xai/grok-4"`, `"groq/..."` — is routed through AI Gateway.
11
+
12
+
```typescript
13
+
exportclassMyAgentextendsThink<Env> {
14
+
getModel() {
15
+
return"@cf/moonshotai/kimi-k2.7-code"; // or "openai/gpt-5.5"
16
+
}
17
+
}
18
+
```
19
+
20
+
Returning a fully-constructed AI SDK `LanguageModel` from `getModel()` still works unchanged for any other provider or for full control over provider/gateway options. A new `getAIBinding()` override (default `this.env.AI`) controls which binding the string resolver uses.
21
+
22
+
Because `getModel()` may now return a bare string, a new public `resolveModel(model?)` method (defaults to resolving `getModel()`) returns a concrete `LanguageModel`. Use it for side inference calls — e.g. summarization/compaction `generateText` — instead of passing `getModel()` straight to the AI SDK.
23
+
24
+
The per-turn override `TurnConfig.model` (returned from `beforeTurn`) also accepts a `ThinkModel` now, so you can switch models for a turn with a plain string (e.g. a cheaper model for continuations). The per-step override `StepConfig.model` (returned from `beforeStep`) accepts a `ThinkModel` too — Think resolves a string back into a `LanguageModel` before handing the step to the AI SDK.
25
+
26
+
`getModel()` is typed to return `ThinkModel` (a newly exported alias for `LanguageModel | ThinkModelId`). `ThinkModelId` (also exported) gives editor autocomplete for the Workers AI text-generation catalog (`@cf/...`, derived from the installed `@cloudflare/workers-types`) while still accepting any string — gateway catalog slugs like `"openai/gpt-5.5"` are validated at runtime, since the catalog lives server-side and is not knowable from types.
Think bundles [`workers-ai-provider`](https://www.npmjs.com/package/workers-ai-provider), so you do not need to install or import it for the common case — `getModel()` can return a model id string (see below).
|`getModel()`| throws | Return the `LanguageModel` to use |
843
+
|`getModel()`| throws | Return a model id `string` (resolved via the bundled `workers-ai-provider` off `getAIBinding()` — a `@cf/...` id hits Workers AI, a `"provider/model"` slug routes through AI Gateway) or a `LanguageModel`|
844
+
|`getAIBinding()`|`this.env.AI`| Workers AI binding used to resolve string models from `getModel()`|
842
845
|`getSystemPrompt()`|`"You are a helpful assistant."`| System prompt (fallback when no context blocks) |
843
846
|`getTools()`|`{}`| AI SDK `ToolSet` for the agentic loop |
844
847
|`getScheduledTasks()`|`{}`| Code-declared recurring prompts or handlers |
@@ -1087,7 +1090,7 @@ export class MyAgent extends Think<Env> {
0 commit comments