Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export interface MyConfig {
- All exported functions, classes, and interfaces must have TSDoc
- Include `@param` for all parameters
- Include `@returns` for return values
- Include `@example` only for exported classes (main SDK entry points like BedrockModel, Agent)
- Include `@example` only for exported classes (main SDK entry points like ConverseModel, Agent)
- Do NOT include `@example` for type definitions, interfaces, or internal types
- Interface properties MUST have single-line descriptions
- Interface properties MAY include an optional `@see` link for additional details
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ Switch between model providers easily:
**Amazon Bedrock (Default)**

```typescript
import { Agent, BedrockModel } from '@strands-agents/sdk'
import { Agent, ConverseModel } from '@strands-agents/sdk'

const model = new BedrockModel({
const model = new ConverseModel({
region: 'us-east-1',
modelId: 'anthropic.claude-3-5-sonnet-20240620-v1:0',
maxTokens: 4096,
Expand All @@ -114,10 +114,10 @@ const agent = new Agent({ model })

```typescript
import { Agent } from '@strands-agents/sdk'
import { OpenAIModel } from '@strands-agents/sdk/openai'
import { ChatModel } from '@strands-agents/sdk/models/openai'

// Automatically uses process.env.OPENAI_API_KEY and defaults to gpt-4o
const model = new OpenAIModel()
const model = new ChatModel()

const agent = new Agent({ model })
```
Expand Down Expand Up @@ -243,9 +243,9 @@ Coordinate multiple agents using built-in orchestration patterns.
**Graph** — You define a deterministic execution plan. Agents run as nodes in a directed graph, with edges controlling execution order. Parallel execution is supported, and downstream nodes run once all dependencies complete.

```typescript
import { Agent, BedrockModel, Graph } from '@strands-agents/sdk'
import { Agent, ConverseModel, Graph } from '@strands-agents/sdk'

const model = new BedrockModel({ maxTokens: 1024 })
const model = new ConverseModel({ maxTokens: 1024 })

const researcher = new Agent({
model,
Expand All @@ -270,9 +270,9 @@ const result = await graph.invoke('What is the largest ocean?')
**Swarm** — The agents decide the routing. Each agent chooses whether to hand off to another agent or produce a final response, making the execution path dynamic and model-driven.

```typescript
import { Agent, BedrockModel, Swarm } from '@strands-agents/sdk'
import { Agent, ConverseModel, Swarm } from '@strands-agents/sdk'

const model = new BedrockModel({ maxTokens: 1024 })
const model = new ConverseModel({ maxTokens: 1024 })

const researcher = new Agent({
model,
Expand Down
8 changes: 4 additions & 4 deletions docs/PR.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Leave these out of your PR description:
### Type Definition Updates

- Added ApiKeySetter type import from 'openai/client'
- Updated OpenAIModelOptions interface apiKey type
- Updated ChatModelOptions interface apiKey type
```

❌ **Implementation notes reviewers don't need:**
Expand Down Expand Up @@ -101,18 +101,18 @@ preventing users from leveraging these capabilities.
````markdown
## Public API Changes

The `OpenAIModelOptions.apiKey` parameter now accepts either a string or an
The `ChatModelOptions.apiKey` parameter now accepts either a string or an
async function:

```typescript
// Before: only string supported
const model = new OpenAIModel({
const model = new ChatModel({
modelId: 'gpt-4o',
apiKey: 'sk-...',
})

// After: function also supported
const model = new OpenAIModel({
const model = new ChatModel({
modelId: 'gpt-4o',
apiKey: async () => await secretManager.getApiKey(),
})
Expand Down
4 changes: 2 additions & 2 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ it('yields expected stream events', async () => {
**Example Implementation Test:**

```typescript
describe('BedrockModel', () => {
describe('ConverseModel', () => {
it('streams messages correctly', async () => {
const provider = new BedrockModel(config)
const provider = new ConverseModel(config)
const stream = provider.stream(messages)

for await (const event of stream) {
Expand Down
4 changes: 2 additions & 2 deletions examples/agents-as-tools/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Agent, AgentResult, BedrockModel, tool } from '@strands-agents/sdk'
import { Agent, AgentResult, ConverseModel, tool } from '@strands-agents/sdk'
import { z } from 'zod'

/**
Expand All @@ -13,7 +13,7 @@ function extractText(result: AgentResult): string {
return result.lastMessage.content.map((b) => ('text' in b ? b.text : '')).join('')
}

const model = new BedrockModel({ maxTokens: 1024 })
const model = new ConverseModel({ maxTokens: 1024 })

// Specialized tool agents

Expand Down
4 changes: 2 additions & 2 deletions examples/first-agent/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Agent, BedrockModel, tool } from '@strands-agents/sdk'
import { Agent, ConverseModel, tool } from '@strands-agents/sdk'
import { z } from 'zod'

const weatherTool = tool({
Expand Down Expand Up @@ -54,7 +54,7 @@ async function runStreaming(title: string, agent: Agent, prompt: string) {

async function main() {
// 1. Initialize the components
const model = new BedrockModel()
const model = new ConverseModel()

// 2. Create agents
const defaultAgent = new Agent()
Expand Down
4 changes: 2 additions & 2 deletions examples/graph/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Agent, BedrockModel, Graph } from '@strands-agents/sdk'
import { Agent, ConverseModel, Graph } from '@strands-agents/sdk'

async function main() {
const model = new BedrockModel({ maxTokens: 1024 })
const model = new ConverseModel({ maxTokens: 1024 })

// Define agents as graph nodes
const researcher = new Agent({
Expand Down
1 change: 0 additions & 1 deletion examples/mcp/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Agent, McpClient } from '@strands-agents/sdk'
import { OpenAIModel } from '../../../dist/src/models/openai.js'
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'

Expand Down
4 changes: 2 additions & 2 deletions examples/swarm/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Agent, BedrockModel, Swarm } from '@strands-agents/sdk'
import { Agent, ConverseModel, Swarm } from '@strands-agents/sdk'

async function main() {
const model = new BedrockModel({ maxTokens: 1024 })
const model = new ConverseModel({ maxTokens: 1024 })

// Define swarm agents with descriptions (used for routing decisions)
const researcher = new Agent({
Expand Down
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
"./anthropic": {
"./models/anthropic": {
"types": "./dist/src/models/anthropic.d.ts",
"default": "./dist/src/models/anthropic.js"
},
"./openai": {
"types": "./dist/src/models/openai.d.ts",
"default": "./dist/src/models/openai.js"
},
"./bedrock": {
"./models/bedrock": {
"types": "./dist/src/models/bedrock.d.ts",
"default": "./dist/src/models/bedrock.js"
},
"./gemini": {
"types": "./dist/src/models/gemini/model.d.ts",
"default": "./dist/src/models/gemini/model.js"
"./models/google": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the models prefix here? Is it for tree shaking?

Copy link
Member Author

@pgrayy pgrayy Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just for namespacing:

import { ChatModel } from '@strands-agents/sdk/models/openai'

vs

import { ChatModel } from '@strands-agents/sdk/openai'

Tree shaking works just the same.

"types": "./dist/src/models/google/index.d.ts",
"default": "./dist/src/models/google/index.js"
},
"./models/openai": {
"types": "./dist/src/models/openai.d.ts",
"default": "./dist/src/models/openai.js"
},
"./multiagent": {
"types": "./dist/src/multiagent/index.d.ts",
Expand Down
14 changes: 7 additions & 7 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ describe('index', () => {
expect(SDK.ContextWindowOverflowError).toBeDefined()
})

it('exports BedrockModel', () => {
expect(SDK.BedrockModel).toBeDefined()
it('exports ConverseModel', () => {
expect(SDK.ConverseModel).toBeDefined()
})

it('can instantiate BedrockModel', () => {
const provider = new SDK.BedrockModel({ region: 'us-west-2' })
expect(provider).toBeInstanceOf(SDK.BedrockModel)
it('can instantiate ConverseModel', () => {
const provider = new SDK.ConverseModel({ region: 'us-west-2' })
expect(provider).toBeInstanceOf(SDK.ConverseModel)
expect(provider.getConfig()).toBeDefined()
})

Expand All @@ -24,10 +24,10 @@ describe('index', () => {
// Error types
contextError: typeof SDK.ContextWindowOverflowError
// Model provider
provider: typeof SDK.BedrockModel
provider: typeof SDK.ConverseModel
} = {
contextError: SDK.ContextWindowOverflowError,
provider: SDK.BedrockModel,
provider: SDK.ConverseModel,
}
expect(_typeCheck).toBeDefined()
})
Expand Down
28 changes: 14 additions & 14 deletions src/agent/__tests__/agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '../../index.js'
import { AgentPrinter } from '../printer.js'
import { BeforeInvocationEvent, BeforeToolsEvent } from '../../hooks/events.js'
import { BedrockModel } from '../../models/bedrock.js'
import { ConverseModel } from '../../models/bedrock.js'
import { StructuredOutputError } from '../../errors.js'
import { expectLoopMetrics } from '../../__fixtures__/metrics-helpers.js'
import { expectAgentResult } from '../../__fixtures__/agent-helpers.js'
Expand Down Expand Up @@ -797,11 +797,11 @@ describe('Agent', () => {
expect(agent.model).toBe(model)
})

it('returns default BedrockModel when no model provided', () => {
it('returns default ConverseModel when no model provided', () => {
const agent = new Agent()

expect(agent.model).toBeDefined()
expect(agent.model.constructor.name).toBe('BedrockModel')
expect(agent.model.constructor.name).toBe('ConverseModel')
})
})

Expand Down Expand Up @@ -1097,25 +1097,25 @@ describe('Agent', () => {

describe('model initialization', () => {
describe('when model is a string', () => {
it('creates BedrockModel with specified modelId', () => {
it('creates ConverseModel with specified modelId', () => {
const agent = new Agent({ model: 'anthropic.claude-3-5-sonnet-20240620-v1:0' })

expect(agent.model).toBeDefined()
expect(agent.model.constructor.name).toBe('BedrockModel')
expect(agent.model.constructor.name).toBe('ConverseModel')
expect(agent.model.getConfig().modelId).toBe('anthropic.claude-3-5-sonnet-20240620-v1:0')
})

it('creates BedrockModel with custom model ID', () => {
it('creates ConverseModel with custom model ID', () => {
const customModelId = 'custom.model.id'
const agent = new Agent({ model: customModelId })

expect(agent.model.getConfig().modelId).toBe(customModelId)
})
})

describe('when model is explicit BedrockModel', () => {
it('uses provided BedrockModel instance', () => {
const explicitModel = new BedrockModel({ modelId: 'explicit-model-id' })
describe('when model is explicit ConverseModel', () => {
it('uses provided ConverseModel instance', () => {
const explicitModel = new ConverseModel({ modelId: 'explicit-model-id' })
const agent = new Agent({ model: explicitModel })

expect(agent.model).toBe(explicitModel)
Expand All @@ -1124,23 +1124,23 @@ describe('Agent', () => {
})

describe('when no model is provided', () => {
it('creates default BedrockModel', () => {
it('creates default ConverseModel', () => {
const agent = new Agent()

expect(agent.model).toBeDefined()
expect(agent.model.constructor.name).toBe('BedrockModel')
expect(agent.model.constructor.name).toBe('ConverseModel')
})
})

describe('behavior parity', () => {
it('string model behaves identically to explicit BedrockModel with same modelId', () => {
it('string model behaves identically to explicit ConverseModel with same modelId', () => {
const modelId = 'anthropic.claude-3-5-sonnet-20240620-v1:0'

// Create agent with string model ID
const agentWithString = new Agent({ model: modelId })

// Create agent with explicit BedrockModel
const explicitModel = new BedrockModel({ modelId })
// Create agent with explicit ConverseModel
const explicitModel = new ConverseModel({ modelId })
const agentWithExplicit = new Agent({ model: explicitModel })

// Both should have same modelId
Expand Down
14 changes: 7 additions & 7 deletions src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type InvokeOptions,
type LocalAgent,
} from '../types/agent.js'
import { BedrockModel } from '../models/bedrock.js'
import { ConverseModel } from '../models/bedrock.js'
import {
contentBlockFromData,
type ContentBlock,
Expand Down Expand Up @@ -79,18 +79,18 @@ export type AgentConfig = {
/**
* The model instance that the agent will use to make decisions.
* Accepts either a Model instance or a string representing a Bedrock model ID.
* When a string is provided, it will be used to create a BedrockModel instance.
* When a string is provided, it will be used to create a ConverseModel instance.
*
* @example
* ```typescript
* // Using a string model ID (creates BedrockModel)
* // Using a string model ID (creates ConverseModel)
* const agent = new Agent({
* model: 'anthropic.claude-3-5-sonnet-20240620-v1:0'
* })
*
* // Using an explicit BedrockModel instance with configuration
* // Using an explicit ConverseModel instance with configuration
* const agent = new Agent({
* model: new BedrockModel({
* model: new ConverseModel({
* modelId: 'anthropic.claude-3-5-sonnet-20240620-v1:0',
* temperature: 0.7,
* maxTokens: 2048
Expand Down Expand Up @@ -230,9 +230,9 @@ export class Agent implements LocalAgent, InvokableAgent {
if (config?.description !== undefined) this.description = config.description

if (typeof config?.model === 'string') {
this.model = new BedrockModel({ modelId: config.model })
this.model = new ConverseModel({ modelId: config.model })
} else {
this.model = config?.model ?? new BedrockModel()
this.model = config?.model ?? new ConverseModel()
}

const { tools, mcpClients } = flattenTools(config?.tools ?? [])
Expand Down
10 changes: 5 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ export type { BaseModelConfig, StreamOptions, CacheConfig } from './models/model
export { Model } from './models/model.js'

// Bedrock model provider
export { BedrockModel as BedrockModel } from './models/bedrock.js'
export { ConverseModel } from './models/bedrock.js'
export type {
BedrockModelConfig,
BedrockModelOptions,
BedrockGuardrailConfig,
BedrockGuardrailRedactionConfig,
ConverseModelConfig,
ConverseModelOptions,
ConverseGuardrailConfig,
ConverseGuardrailRedactionConfig,
} from './models/bedrock.js'

// Agent streaming event types
Expand Down
Loading