Skip to content
Merged
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
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,10 @@ All checks must pass before commit is allowed.
- No semicolons
- Single quotes
- Line length: 120 characters
- Line length for doc snippet files under `src/content/docs/`: 90 characters
- Tab width: 2 spaces
- Trailing commas in ES5 style
- Template literal contents in doc snippets must also stay under 90 characters per line. Prettier does not enforce this automatically.

**Example**:
```typescript
Expand Down Expand Up @@ -288,8 +290,8 @@ const result = await agent.invoke('Hello')
{
"scripts": {
"test": "tsc --noEmit",
"format": "prettier --write docs",
"format:check": "prettier --check docs"
"format": "prettier --write docs 'src/content/docs/**/*.ts'",
"format:check": "prettier --check docs 'src/content/docs/**/*.ts'"
}
}
```
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ npm run format:check # formatting

Pre-commit hooks run these automatically.

### Sync Docs with Source Code Updates

After merging source code changes, run

```bash
npm run sdk:sync
```

to make the doc types and generated API pages even with the new source code state.
New implementations should link to the API page from the User Guide.

## Reporting Bugs/Feature Requests

Expand Down
15 changes: 12 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
"test": "vitest run",
"typecheck": "tsc --noEmit",
"typecheck:snippets": "npm run typecheck --prefix test-snippets",
"format": "prettier --write docs",
"format:check": "prettier --check docs",
"format": "prettier --write docs 'src/content/docs/**/*.ts'",
"format:check": "prettier --check docs 'src/content/docs/**/*.ts'",
"clean": "rm -rf .build && rm -rf .astro",
"preview": "astro preview",
"cms:build": "npm run build:all",
"sdk:clone": "tsx scripts/clone-sdks.ts",
"sdk:generate:py": "command -v uv >/dev/null 2>&1 && uv run scripts/api-generation-python.py || (pip install pydoc-markdown>=4.8.2 && python scripts/api-generation-python.py)",
"sdk:generate:ts": "tsx scripts/api-generation-typescript.ts",
"sdk:generate": "npm run sdk:generate:py && npm run sdk:generate:ts",
"sdk:sync": "npm upgrade @strands-agents/sdk && npm run sdk:clone && npm run sdk:generate",
"routes:update": "tsx scripts/update-known-routes.ts",
"astro": "astro"
},
Expand Down Expand Up @@ -76,6 +77,14 @@
"singleQuote": true,
"printWidth": 120,
"tabWidth": 2,
"trailingComma": "es5"
"trailingComma": "es5",
"overrides": [
{
"files": "src/content/docs/**/*.ts",
"options": {
"printWidth": 90
}
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,10 @@ The `per_turn` parameter accepts:

### SummarizingConversationManager

{/* https://github.com/strands-agents/sdk-typescript/issues/279 */}
:::note[Not supported in TypeScript]
The [`SummarizingConversationManager`](@api/python/strands.agent.conversation_manager.summarizing_conversation_manager#SummarizingConversationManager) (Python) / [`SummarizingConversationManager`](@api/typescript/SummarizingConversationManager) (TypeScript) implements intelligent conversation context management by summarizing older messages instead of simply discarding them. This approach preserves important information while staying within context limits.

:::

The [`SummarizingConversationManager`](@api/python/strands.agent.conversation_manager.summarizing_conversation_manager#SummarizingConversationManager) implements intelligent conversation context management by summarizing older messages instead of simply discarding them. This approach preserves important information while staying within context limits.
<Tabs>
<Tab label="Python">

Configuration parameters:

Expand All @@ -153,13 +151,26 @@ Configuration parameters:
- **`summarization_agent`** (Agent, optional): Custom agent for generating summaries. If not provided, uses the main agent instance. Cannot be used together with `summarization_system_prompt`.
- **`summarization_system_prompt`** (str, optional): Custom system prompt for summarization. If not provided, uses a default prompt that creates structured bullet-point summaries focusing on key topics, tools used, and technical information in third-person format. Cannot be used together with `summarization_agent`.

**Basic Usage:**
</Tab>
<Tab label="TypeScript">

By default, the `SummarizingConversationManager` leverages the same model and configuration as your main agent to perform summarization.
Configuration parameters:

- **`model`** (Model, optional): Override model to use for generating summaries. When not provided, uses the agent's own model.
- **`summaryRatio`** (number, default: 0.3): Ratio of messages to summarize when reducing context (clamped between 0.1 and 0.8)
- **`preserveRecentMessages`** (number, default: 10): Minimum number of recent messages to always keep
- **`summarizationSystemPrompt`** (string, optional): Custom system prompt for summarization. If not provided, uses a default prompt that creates structured bullet-point summaries focusing on key topics, tools used, and technical information in third-person format.

</Tab>
</Tabs>

**Basic Usage:**

<Tabs>
<Tab label="Python">

By default, the `SummarizingConversationManager` leverages the same model and configuration as your main agent to perform summarization.

```python
from strands import Agent
from strands.agent.conversation_manager import SummarizingConversationManager
Expand All @@ -171,8 +182,12 @@ agent = Agent(
</Tab>
<Tab label="TypeScript">

```ts
// Not supported in TypeScript
By default, the `SummarizingConversationManager` uses the agent's own model for summarization. You can optionally provide a different model to override this behavior.

```typescript
--8<-- "user-guide/concepts/agents/conversation-management_imports.ts:summarizing_conversation_manager_basic_imports"

--8<-- "user-guide/concepts/agents/conversation-management.ts:summarizing_conversation_manager_basic"
```
</Tab>
</Tabs>
Expand All @@ -199,8 +214,10 @@ agent = Agent(
</Tab>
<Tab label="TypeScript">

```ts
// Not supported in TypeScript
```typescript
--8<-- "user-guide/concepts/agents/conversation-management_imports.ts:summarizing_conversation_manager_custom_imports"

--8<-- "user-guide/concepts/agents/conversation-management.ts:summarizing_conversation_manager_custom"
```
</Tab>
</Tabs>
Expand Down Expand Up @@ -238,19 +255,21 @@ agent = Agent(
</Tab>
<Tab label="TypeScript">

```ts
// Not supported in TypeScript
```typescript
--8<-- "user-guide/concepts/agents/conversation-management_imports.ts:summarizing_conversation_manager_system_prompt_imports"

--8<-- "user-guide/concepts/agents/conversation-management.ts:summarizing_conversation_manager_system_prompt"
```
</Tab>
</Tabs>

**Advanced Configuration with Custom Summarization Agent:**

For advanced use cases, you can provide a custom `summarization_agent` to handle the summarization process. This enables using a different model (such as a faster or a more cost-effective one), incorporating tools during summarization, or implementing specialized summarization logic tailored to your domain. The custom agent can leverage its own system prompt, tools, and model configuration to generate summaries that best preserve the essential context for your specific use case.

<Tabs>
<Tab label="Python">

For advanced use cases, you can provide a custom `summarization_agent` to handle the summarization process. This enables using a different model (such as a faster or a more cost-effective one), incorporating tools during summarization, or implementing specialized summarization logic tailored to your domain. The custom agent can leverage its own system prompt, tools, and model configuration to generate summaries that best preserve the essential context for your specific use case.

```python
from strands import Agent
from strands.agent.conversation_manager import SummarizingConversationManager
Expand Down Expand Up @@ -283,7 +302,7 @@ agent = Agent(
</Tab>
</Tabs>

Key features of the `SummarizingConversationManager`:
#### Key Features

- **Context Window Management**: Automatically reduces context when token limits are exceeded
Comment thread
notowen333 marked this conversation as resolved.
- **Intelligent Summarization**: Uses structured bullet-point summaries to capture key information
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Agent, ConversationManager, AfterInvocationEvent, NullConversationManager, SlidingWindowConversationManager } from '@strands-agents/sdk'
import {
Agent,
ConversationManager,
AfterInvocationEvent,
NullConversationManager,
SlidingWindowConversationManager,
SummarizingConversationManager,
BedrockModel,
} from '@strands-agents/sdk'
import type { LocalAgent, ConversationManagerReduceOptions } from '@strands-agents/sdk'

async function nullConversationManagerAgent() {
Expand Down Expand Up @@ -62,3 +70,54 @@ class MyManager extends ConversationManager {
}
}
// --8<-- [end:custom_conversation_manager_proactive]

async function summarizingBasic() {
// --8<-- [start:summarizing_conversation_manager_basic]
const agent = new Agent({
conversationManager: new SummarizingConversationManager(),
})
// --8<-- [end:summarizing_conversation_manager_basic]
}

async function summarizingCustom() {
// --8<-- [start:summarizing_conversation_manager_custom]
// Optionally use a different model for summarization
const summarizationModel = new BedrockModel({
modelId: 'anthropic.claude-sonnet-4-20250514-v1:0',
})

const conversationManager = new SummarizingConversationManager({
model: summarizationModel, // Override the agent's model for summarization
summaryRatio: 0.3, // Summarize 30% of messages when context reduction is needed
preserveRecentMessages: 10, // Always keep 10 most recent messages
})

const agent = new Agent({
conversationManager,
})
// --8<-- [end:summarizing_conversation_manager_custom]
}

async function summarizingSystemPrompt() {
// --8<-- [start:summarizing_conversation_manager_system_prompt]
// Custom system prompt for technical conversations
const customSystemPrompt = `
You are summarizing a technical conversation.
Create a concise bullet-point summary that:
- Focuses on code changes, architectural decisions, and technical solutions
- Preserves specific function names, file paths, and configuration details
- Omits conversational elements and focuses on actionable information
- Uses technical terminology appropriate for software development

Format as bullet points without conversational language.
`

const conversationManager = new SummarizingConversationManager({
summarizationSystemPrompt: customSystemPrompt,
})

const agent = new Agent({
conversationManager,
})
// --8<-- [end:summarizing_conversation_manager_system_prompt]
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,31 @@ import { Agent, SlidingWindowConversationManager } from '@strands-agents/sdk'
// --8<-- [end:sliding_window_conversation_manager_imports]

// --8<-- [start:custom_conversation_manager_imports]
import { Agent, ConversationManager, type ConversationManagerReduceOptions } from '@strands-agents/sdk'
import {
Agent,
ConversationManager,
type ConversationManagerReduceOptions,
} from '@strands-agents/sdk'
// --8<-- [end:custom_conversation_manager_imports]

// --8<-- [start:custom_conversation_manager_proactive_imports]
import { Agent, ConversationManager, AfterInvocationEvent, type AgentData, type ConversationManagerReduceOptions } from '@strands-agents/sdk'
import {
Agent,
ConversationManager,
AfterInvocationEvent,
type AgentData,
type ConversationManagerReduceOptions,
} from '@strands-agents/sdk'
// --8<-- [end:custom_conversation_manager_proactive_imports]

// --8<-- [start:summarizing_conversation_manager_basic_imports]
import { Agent, SummarizingConversationManager } from '@strands-agents/sdk'
// --8<-- [end:summarizing_conversation_manager_basic_imports]

// --8<-- [start:summarizing_conversation_manager_custom_imports]
import { Agent, SummarizingConversationManager, BedrockModel } from '@strands-agents/sdk'
// --8<-- [end:summarizing_conversation_manager_custom_imports]

// --8<-- [start:summarizing_conversation_manager_system_prompt_imports]
import { Agent, SummarizingConversationManager } from '@strands-agents/sdk'
// --8<-- [end:summarizing_conversation_manager_system_prompt_imports]
40 changes: 32 additions & 8 deletions src/content/docs/user-guide/concepts/agents/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import {
AfterModelCallEvent,
MessageAddedEvent,
} from '@strands-agents/sdk'
import { Graph, Swarm, BeforeNodeCallEvent, AfterNodeCallEvent } from '@strands-agents/sdk/multiagent'
import {
Graph,
Swarm,
BeforeNodeCallEvent,
AfterNodeCallEvent,
} from '@strands-agents/sdk/multiagent'
import type { MultiAgent, MultiAgentPlugin } from '@strands-agents/sdk/multiagent'

// Mock tools for examples
Expand Down Expand Up @@ -108,7 +113,9 @@ async function resultModificationExample() {
private processResult(event: AfterToolCallEvent): void {
if (event.toolUse.name === 'calculator') {
// Add formatting to calculator results
const textContent = event.result.content.find((block) => block.type === 'textBlock')
const textContent = event.result.content.find(
(block) => block.type === 'textBlock'
)
if (textContent && textContent.type === 'textBlock') {
// Note: In actual implementation, result modification may work differently
console.log(`Would modify result: ${textContent.text}`)
Expand Down Expand Up @@ -162,7 +169,9 @@ async function loggingModificationsExample() {

private processResult(event: AfterToolCallEvent): void {
if (event.toolUse.name === 'calculator') {
const textContent = event.result.content.find((block) => block.type === 'textBlock')
const textContent = event.result.content.find(
(block) => block.type === 'textBlock'
)
if (textContent && textContent.type === 'textBlock') {
const originalContent = textContent.text
console.log(`Modifying calculator result: ${originalContent}`)
Expand Down Expand Up @@ -284,8 +293,14 @@ async function limitToolCountsExample() {

async function orchestratorCallbackExample() {
// --8<-- [start:orchestrator_callback]
const researcher = new Agent({ id: 'researcher', systemPrompt: 'You are a research specialist.' })
const writer = new Agent({ id: 'writer', systemPrompt: 'You are a writing specialist.' })
const researcher = new Agent({
id: 'researcher',
systemPrompt: 'You are a research specialist.',
})
const writer = new Agent({
id: 'writer',
systemPrompt: 'You are a writing specialist.',
})

const graph = new Graph({
nodes: [researcher, writer],
Expand All @@ -305,9 +320,18 @@ async function orchestratorCallbackExample() {

async function conditionalNodeExecutionExample() {
// --8<-- [start:conditional_node_execution]
const researcher = new Agent({ id: 'researcher', systemPrompt: 'You are a research specialist.' })
const writer = new Agent({ id: 'writer', systemPrompt: 'You are a writing specialist.' })
const reviewer = new Agent({ id: 'reviewer', systemPrompt: 'You are a review specialist.' })
const researcher = new Agent({
id: 'researcher',
systemPrompt: 'You are a research specialist.',
})
const writer = new Agent({
id: 'writer',
systemPrompt: 'You are a writing specialist.',
})
const reviewer = new Agent({
id: 'reviewer',
systemPrompt: 'You are a review specialist.',
})

const graph = new Graph({
nodes: [researcher, writer, reviewer],
Expand Down
Loading
Loading