diff --git a/.agents/references/code-verification.md b/.agents/references/code-verification.md index f7a1f863d0..57af498221 100644 --- a/.agents/references/code-verification.md +++ b/.agents/references/code-verification.md @@ -68,11 +68,11 @@ If the clones aren't present, run `npm run sdk:clone` from `site/`, or fall back If the local clones aren't available, fetch source through the GitHub API: ```bash -# Python SDK -gh api repos/strands-agents/sdk-python/contents/src/strands/[path] +# Python SDK (now local at strands-py/src/strands/) +gh api repos/strands-agents/sdk-python/contents/strands-py/src/strands/[path] -# TypeScript SDK -gh api repos/strands-agents/sdk-typescript/contents/strands-ts/src/[path] +# TypeScript SDK (now local at strands-ts/src/) +gh api repos/strands-agents/sdk-python/contents/strands-ts/src/[path] ``` ## Tier 3: Installed Package Introspection diff --git a/.agents/skills/strands-review/SKILL.md b/.agents/skills/strands-review/SKILL.md index 0defa55b4c..2737067c4f 100644 --- a/.agents/skills/strands-review/SKILL.md +++ b/.agents/skills/strands-review/SKILL.md @@ -10,20 +10,6 @@ same findings as the remote `/strands review` agent. If the upstream changes, re-sync from the source URL above. Do not edit the body to fit local conventions — divergence here defeats the purpose of the skill. -NOTE: an SDK monorepo merge is imminent (sdk-typescript + sdk-python + -devtools). Once that lands, the upstream SOP lives in-tree at something like -`devtools/strands-command/agent-sops/task-reviewer.sop.md` instead of a -separate repo. At that point: - - Replace this file with a symlink to the in-tree SOP (or `include` it via - a build step) so re-sync is automatic and drift is impossible. - - The `source:` URL in frontmatter becomes a relative repo path. - - The "re-sync from source URL" instruction below becomes obsolete — a - `git pull` is the sync. -Until then, re-sync manually: - curl -sL https://raw.githubusercontent.com/strands-agents/devtools/main/strands-command/agent-sops/task-reviewer.sop.md \ - > .agents/skills/strands-review/SKILL.md.body - # then splice the new body in below this comment block - Tool-name mapping (the SOP names upstream Strands tools; locally use these): - `get_pr_files` -> `gh pr view --json files` / `gh pr diff ` - `add_pr_comment` (inline) -> `gh api repos/{owner}/{repo}/pulls/{pr}/comments` @@ -48,7 +34,7 @@ Initialize the review environment by checking out the main branch for guidance. - You MUST checkout the main branch first to read repository review guidance - You MUST create a progress notebook to track your review process using markdown checklists - You MUST read repository guidelines from `README.md`, `CONTRIBUTING.md`, and `AGENTS.md` (if present) -- You MUST read API bar raising guidelines from https://github.com/strands-agents/docs/blob/main/team/API_BAR_RAISING.md +- You MUST read API bar raising guidelines from `team/API_BAR_RAISING.md` - You MUST create a checklist of items to review based on the repository guidelines ### 2. Analyze Pull Request Context @@ -97,7 +83,7 @@ If the PR introduces or modifies public APIs, evaluate the API design from a cus - Example code snippets demonstrating usage - Complete API signatures with default parameter values - Module exports (what's exported from each module) -- You MUST evaluate the API against SDK tenets (https://github.com/strands-agents/docs/blob/main/team/TENETS.md) and decision records (https://github.com/strands-agents/docs/blob/main/team/DECISIONS.md) +- You MUST evaluate the API against SDK tenets (`team/TENETS.md`) and decision records (`team/DECISIONS.md`) - You MUST verify the API addresses documented use cases - You MUST check if default parameters/behavior represent the most common usage - You MUST assess the level of abstraction and extensibility: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 4c4b04753f..2db42ba4d0 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -5,5 +5,5 @@ contact_links: url: https://github.com/strands-agents/sdk-python/discussions about: Please ask and answer questions here - name: Strands Agents SDK Documentation - url: https://github.com/strands-agents/docs + url: https://strandsagents.com about: Visit our documentation for help diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index fa894231b9..fc5fea9c0c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,7 +7,7 @@ ## Documentation PR - + ## Type of Change diff --git a/AGENTS.md b/AGENTS.md index 1c16778b78..d7bf0abc71 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,1075 +1,33 @@ -# Agent Development Guide - Strands TypeScript SDK +# Agent Development Guide - Strands Agents Monorepo -This document provides guidance specifically for AI agents working on the Strands TypeScript SDK codebase. For human contributor guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). +This document provides guidance for AI agents working in the Strands Agents monorepo. For human contributor guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). -## Purpose and Scope +## Monorepo Layout -**AGENTS.md** contains agent-specific repository information including: - -- Directory structure with summaries of what is included in each directory -- Development workflow instructions for agents to follow when developing features -- Coding patterns and testing patterns to follow when writing code -- Style guidelines, organizational patterns, and best practices - -**For human contributors**: See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, testing, and contribution guidelines. - -## Directory Structure - -The repo is an npm workspace monorepo. The root `package.json` delegates all build/test/lint commands to the `strands-ts` workspace package. - -``` -sdk-typescript/ -├── strands-ts/ # SDK workspace package -│ ├── src/ # All production code -│ │ ├── __fixtures__/ # Shared test fixtures (mocks, helpers) -│ │ ├── __tests__/ # Unit tests for root-level source files -│ │ │ -│ │ ├── a2a/ # Agent-to-agent protocol -│ │ │ ├── __tests__/ -│ │ │ ├── a2a-agent.ts # A2A agent client -│ │ │ ├── adapters.ts # Strands/A2A type converters -│ │ │ ├── events.ts # A2A streaming events -│ │ │ ├── executor.ts # A2A executor -│ │ │ ├── express-server.ts # Express-based A2A server -│ │ │ ├── logging.ts # A2A-specific logging -│ │ │ ├── server.ts # A2A server base -│ │ │ └── index.ts -│ │ │ -│ │ ├── agent/ # Agent loop and streaming -│ │ │ ├── __tests__/ -│ │ │ ├── agent.ts # Core agent implementation -│ │ │ ├── agent-as-tool.ts # Wrap agent as a tool -│ │ │ ├── printer.ts # Agent output printing -│ │ │ ├── snapshot.ts # Agent state snapshots -│ │ │ └── tool-caller.ts # Direct tool calling via agent.tool accessor -│ │ │ -│ │ ├── conversation-manager/ # Conversation history strategies -│ │ │ ├── __tests__/ -│ │ │ ├── conversation-manager.ts -│ │ │ ├── null-conversation-manager.ts -│ │ │ ├── sliding-window-conversation-manager.ts -│ │ │ ├── summarizing-conversation-manager.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── hooks/ # Hooks system for extensibility -│ │ │ ├── __tests__/ -│ │ │ ├── events.ts -│ │ │ ├── registry.ts -│ │ │ ├── types.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── logging/ # Structured logging -│ │ │ ├── __tests__/ -│ │ │ ├── logger.ts -│ │ │ ├── warn-once.ts # Dedupe warnings by message content -│ │ │ ├── types.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── models/ # Model provider implementations -│ │ │ ├── __tests__/ -│ │ │ ├── google/ # Google Gemini provider -│ │ │ │ ├── adapters.ts -│ │ │ │ ├── errors.ts -│ │ │ │ ├── model.ts -│ │ │ │ ├── types.ts -│ │ │ │ └── index.ts -│ │ │ ├── openai/ # OpenAI provider (Chat Completions + Responses API) -│ │ │ │ ├── __tests__/ # Unit tests (chat.test.ts, responses.test.ts) -│ │ │ │ ├── chat-adapter.ts -│ │ │ │ ├── responses-adapter.ts -│ │ │ │ ├── formatting.ts -│ │ │ │ ├── errors.ts -│ │ │ │ ├── model.ts -│ │ │ │ ├── types.ts -│ │ │ │ └── index.ts -│ │ │ ├── anthropic.ts # Anthropic Claude -│ │ │ ├── bedrock.ts # AWS Bedrock -│ │ │ ├── vercel.ts # Vercel AI SDK -│ │ │ ├── defaults.ts # Centralized model defaults + warning messages -│ │ │ ├── model.ts # Base model interface -│ │ │ └── streaming.ts # Streaming event types -│ │ │ -│ │ ├── multiagent/ # Multi-agent orchestration -│ │ │ ├── __tests__/ -│ │ │ ├── graph.ts # Graph orchestrator (DAG) -│ │ │ ├── swarm.ts # Swarm orchestrator (handoff) -│ │ │ ├── multiagent.ts # Base multi-agent class -│ │ │ ├── nodes.ts # Node types -│ │ │ ├── state.ts # State management -│ │ │ ├── events.ts # Streaming events -│ │ │ ├── edge.ts # Edge definitions -│ │ │ ├── queue.ts # Execution queue -│ │ │ ├── snapshot.ts # Multi-agent snapshots -│ │ │ ├── plugins.ts # Multi-agent plugins -│ │ │ └── index.ts -│ │ │ -│ │ ├── interventions/ # Intervention system for authorization, guardrails, steering -│ │ │ ├── __tests__/ -│ │ │ ├── actions.ts -│ │ │ ├── handler.ts -│ │ │ ├── registry.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── plugins/ # Plugin system -│ │ │ ├── __tests__/ -│ │ │ ├── plugin.ts -│ │ │ ├── registry.ts -│ │ │ ├── model-plugin.ts # Clears agent messages after invocation when model is stateful -│ │ │ └── index.ts -│ │ │ -│ │ ├── registry/ # Tool registry -│ │ │ ├── __tests__/ -│ │ │ └── tool-registry.ts -│ │ │ -│ │ ├── retry/ # Retry strategies for model calls -│ │ │ ├── __tests__/ -│ │ │ ├── backoff-strategy.ts -│ │ │ ├── model-retry-strategy.ts # Abstract ModelRetryStrategy base class -│ │ │ ├── default-model-retry-strategy.ts -│ │ │ ├── retry-strategy.ts # RetryStrategy union type + dedup helper -│ │ │ └── index.ts -│ │ │ -│ │ ├── sandbox/ # Sandbox abstraction for agent code execution -│ │ │ ├── __tests__/ -│ │ │ ├── base.ts # Abstract Sandbox class -│ │ │ ├── posix-shell.ts # PosixShellSandbox with shell-based defaults -│ │ │ ├── stream-process.ts # ChildProcess-to-AsyncGenerator bridge -│ │ │ ├── constants.ts # Language validation pattern -│ │ │ └── types.ts # ExecutionResult, StreamChunk, FileInfo, OutputFile -│ │ │ -│ │ ├── session/ # Session management -│ │ │ ├── __tests__/ -│ │ │ ├── session-manager.ts -│ │ │ ├── storage.ts # Storage interface -│ │ │ ├── file-storage.ts # File-based storage -│ │ │ ├── s3-storage.ts # S3 storage -│ │ │ ├── types.ts -│ │ │ ├── validation.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── telemetry/ # OpenTelemetry tracing and metrics -│ │ │ ├── __tests__/ -│ │ │ ├── tracer.ts -│ │ │ ├── meter.ts -│ │ │ ├── config.ts -│ │ │ ├── json.ts -│ │ │ ├── types.ts -│ │ │ ├── utils.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── tools/ # Tool definitions and types -│ │ │ ├── __tests__/ -│ │ │ ├── function-tool.ts -│ │ │ ├── mcp-tool.ts -│ │ │ ├── noop-tool.ts -│ │ │ ├── structured-output-tool.ts -│ │ │ ├── tool-factory.ts -│ │ │ ├── tool.ts -│ │ │ ├── zod-tool.ts -│ │ │ ├── zod-utils.ts -│ │ │ └── types.ts -│ │ │ -│ │ ├── types/ # Core type definitions -│ │ │ ├── __tests__/ -│ │ │ ├── agent.ts -│ │ │ ├── citations.ts -│ │ │ ├── elicitation.ts -│ │ │ ├── interrupt.ts -│ │ │ ├── json.ts -│ │ │ ├── lifecycle-observer.ts -│ │ │ ├── media.ts -│ │ │ ├── messages.ts -│ │ │ ├── serializable.ts -│ │ │ ├── snapshot.ts -│ │ │ └── validation.ts -│ │ │ -│ │ ├── utils/ # Shared utility functions -│ │ │ └── shell-quote.ts # Shell-safe string escaping -│ │ │ -│ │ ├── vended-interventions/ # Optional vended intervention handlers -│ │ │ ├── hitl/ # Human-in-the-loop approval handler -│ │ │ │ ├── __tests__/ -│ │ │ │ ├── hitl.ts -│ │ │ │ └── index.ts -│ │ │ └── steering/ # Steering handler base + LLM-driven steering -│ │ │ ├── __tests__/ -│ │ │ ├── handlers/ -│ │ │ │ ├── handler.ts -│ │ │ │ └── llm.ts -│ │ │ ├── providers/ -│ │ │ │ ├── context-provider.ts -│ │ │ │ └── tool-ledger.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── vended-plugins/ # Optional vended plugins -│ │ │ ├── index.ts # Barrel export for all plugins -│ │ │ ├── context-offloader/ # Context offloading plugin -│ │ │ │ ├── __tests__/ -│ │ │ │ ├── plugin.ts -│ │ │ │ ├── storage.ts -│ │ │ │ └── index.ts -│ │ │ └── skills/ # AgentSkills plugin -│ │ │ ├── __tests__/ -│ │ │ ├── agent-skills.ts -│ │ │ ├── skill.ts -│ │ │ └── index.ts -│ │ │ -│ │ ├── vended-tools/ # Optional vended tools -│ │ │ ├── index.ts # Barrel export for all tools -│ │ │ ├── bash/ -│ │ │ ├── file-editor/ -│ │ │ ├── http-request/ -│ │ │ └── notebook/ -│ │ │ -│ │ ├── errors.ts # Custom error classes -│ │ ├── index.ts # Main SDK entry point -│ │ ├── interrupt.ts # Interrupt handling -│ │ ├── mcp.ts # MCP client implementation -│ │ ├── mcp-config.ts # MCP config file parsing -│ │ ├── mime.ts # MIME type utilities -│ │ └── state-store.ts # State store implementation -│ │ -│ ├── generated/ # Auto-generated WIT type declarations -│ │ ├── interfaces/ # Per-interface type definitions -│ │ └── strands:agent.d.ts # Top-level WIT agent declaration -│ │ -│ ├── test/ # Tests outside of source -│ │ ├── integ/ # Integration tests -│ │ │ ├── __fixtures__/ # Integration test fixtures -│ │ │ ├── __resources__/ # Static resources for integration tests -│ │ │ ├── a2a/ -│ │ │ ├── conversation-manager/ -│ │ │ ├── mcp/ -│ │ │ ├── models/ -│ │ │ │ └── openai/ -│ │ │ ├── multiagent/ -│ │ │ ├── skills/ -│ │ │ ├── tools/ -│ │ │ └── agent.test.ts -│ │ └── packages/ # Package compatibility tests (CJS/ESM) -│ │ -│ ├── examples/ # Example applications -│ │ ├── agents-as-tools/ -│ │ ├── browser-agent/ -│ │ ├── first-agent/ -│ │ ├── graph/ -│ │ ├── mcp/ -│ │ ├── swarm/ -│ │ └── telemetry/ -│ │ -│ ├── package.json # SDK package config and dependencies -│ ├── tsconfig.base.json # TypeScript configuration -│ ├── vitest.config.ts # Testing configuration -│ └── eslint.config.js # Linting configuration -│ -├── strands-wasm/ # WASM build tooling -│ ├── __fixtures__/ # Vitest module mocks for WIT imports -│ ├── __tests__/ # Unit tests for entry.ts internals -│ ├── generated/ # Auto-generated WIT type declarations -│ │ └── interfaces/ # Per-interface type definitions -│ ├── test/ # Tests outside of source -│ │ └── guest/ # Tests that load the compiled WASM component -│ ├── docs/ # WASM-specific documentation -│ ├── patches/ # Runtime patches for WASM compatibility -│ │ └── getChunkedStream.js -│ ├── entry.ts # WASM entry point (TS SDK surface for WASM compilation) -│ ├── build.js # Build script for WASM compilation -│ ├── package.json # WASM package configuration -│ ├── vitest.config.ts # Test configuration (unit + guest projects) -│ └── tsconfig.json # TypeScript type-check configuration -│ -├── strands-py-wasm/ # Python SDK bindings (WASM-based) -│ ├── strands/ # Python package source -│ │ ├── _generated/ # Auto-generated type bindings -│ │ ├── agent/ # Agent implementation -│ │ │ └── conversation_manager/ -│ │ ├── event_loop/ # Event loop and retry logic -│ │ ├── models/ # Model providers (Bedrock, Anthropic, OpenAI, Gemini) -│ │ ├── multiagent/ # Multi-agent orchestration (Graph, Swarm) -│ │ ├── session/ # Session management (file, S3) -│ │ ├── tools/ # Tool definitions and MCP client -│ │ │ └── mcp/ -│ │ ├── types/ # Type definitions -│ │ ├── _conversions.py # Type conversions between TS and Python -│ │ ├── _wasm_host.py # WASM host runtime bridge -│ │ ├── hooks.py # Hooks system -│ │ └── interrupt.py # Interrupt handling -│ ├── scripts/ # Build/codegen scripts -│ │ └── generate_types.py # Type generation from WIT definitions -│ ├── examples/ # Example applications -│ ├── tests_integ/ # Integration tests -│ ├── pyproject.toml # Python package configuration -│ └── pyrightconfig.json # Python type checking configuration -│ -├── strandly/ # Developer CLI tooling -│ ├── scripts/ -│ │ └── generate_types.py # Type generation script -│ ├── src/ -│ │ └── cli.ts # CLI entry point -│ ├── package.json # Dev CLI package configuration -│ └── tsconfig.json # TypeScript configuration -│ -├── wit/ # WebAssembly Interface Type definitions -│ ├── deps/ # WIT dependency interfaces -│ │ ├── clocks/clocks.wit -│ │ └── io/io.wit -│ ├── agent.wit # Top-level WIT world definition -│ ├── conversation.wit # Conversation management interfaces -│ ├── logging.wit # Logging interfaces -│ ├── mcp.wit # MCP protocol interfaces -│ ├── messages.wit # Message type definitions -│ ├── models.wit # Model provider interfaces -│ ├── multiagent.wit # Multi-agent interfaces -│ ├── retry.wit # Retry strategy interfaces -│ ├── sessions.wit # Session management interfaces -│ ├── streaming.wit # Streaming event interfaces -│ ├── tools.wit # Tool interfaces -│ └── vended.wit # Vended plugin/tool interfaces -│ -├── dev-docs/ # Project documentation -│ ├── TESTING.md # Comprehensive testing guidelines -│ ├── DEPENDENCIES.md # Dependency management guidelines -│ ├── DIVERGENCES.md # Divergences from Python SDK -│ └── PR.md # Pull request guidelines and template -│ -├── .github/ # GitHub configuration -│ ├── ISSUE_TEMPLATE/ # Issue templates (bug report, feature request) -│ ├── PULL_REQUEST_TEMPLATE.md # PR template -│ └── workflows/ # CI/CD workflows -│ -├── .husky/ # Git hooks (pre-commit checks) -│ -├── package.json # Root workspace config (delegates to strands-ts) -├── .prettierrc # Code formatting configuration -├── .gitignore # Git ignore rules -│ -├── AGENTS.md # This file (agent guidance) -├── COMPATIBILITY.MD # Compatibility documentation -├── CONTRIBUTING.md # Human contributor guidelines -└── README.md # Project overview and usage -``` - -### Directory Purposes - -- **`strands-ts/`**: The SDK workspace package containing all source, tests, and examples -- **`strands-ts/src/`**: All production code with co-located unit tests -- **`strands-ts/src/__fixtures__/`**: Shared test fixtures (mock models, helpers) -- **`strands-ts/src/a2a/`**: Agent-to-agent protocol (A2A client, server, adapters, logging) -- **`strands-ts/src/agent/`**: Agent loop coordination, output printing, snapshots -- **`strands-ts/src/conversation-manager/`**: Conversation history management strategies -- **`strands-ts/src/hooks/`**: Hooks system for event-driven extensibility -- **`strands-ts/src/logging/`**: Structured logging utilities -- **`strands-ts/src/models/`**: Model provider implementations (Bedrock, Anthropic, OpenAI, Google, Vercel) -- **`strands-ts/src/multiagent/`**: Multi-agent orchestration patterns (Graph for DAG execution, Swarm for handoff-based routing) -- **`strands-ts/src/plugins/`**: Plugin system for extending agent functionality -- **`strands-ts/src/registry/`**: Tool registry implementation -- **`strands-ts/src/retry/`**: Retry strategies for model calls (backoff strategies, abstract `ModelRetryStrategy` plugin base class, concrete `DefaultModelRetryStrategy`) -- **`strands-ts/src/sandbox/`**: Sandbox abstraction for agent code execution (abstract `Sandbox` base class, `PosixShellSandbox` base for shell-based implementations) -- **`strands-ts/src/session/`**: Session management (file, S3, custom storage) -- **`strands-ts/src/telemetry/`**: OpenTelemetry tracing and metrics -- **`strands-ts/src/tools/`**: Tool definitions, types, and structured output validation with Zod schemas -- **`strands-ts/src/types/`**: Core type definitions used across the SDK -- **`strands-ts/src/utils/`**: Shared utility functions -- **`strands-ts/src/vended-interventions/`**: Optional vended intervention handlers (hitl, steering — not part of core SDK, independently importable) -- **`strands-ts/src/vended-plugins/`**: Optional vended plugins (context-offloader, skills — not part of core SDK, independently importable) -- **`strands-ts/src/vended-tools/`**: Optional vended tools (bash, file-editor, http-request, notebook) -- **`strands-ts/generated/`**: Auto-generated WIT interface type declarations -- **`strands-ts/test/integ/`**: Integration tests (tests public API and external integrations) -- **`strands-ts/examples/`**: Example applications -- **`strands-wasm/`**: WASM build tooling for compiling the TS SDK to WebAssembly -- **`strands-wasm/generated/`**: Auto-generated WIT interface type declarations for WASM -- **`strands-wasm/test/guest/`**: Tests that load the compiled WASM component -- **`strands-wasm/docs/`**: WASM-specific development documentation -- **`strands-py-wasm/`**: Python SDK bindings powered by the TS SDK compiled to WASM -- **`strands-py-wasm/strands/`**: Python package source with agent, models, multiagent, session, tools, and type modules -- **`strands-py-wasm/scripts/`**: Build and codegen scripts (type generation from WIT definitions) -- **`strands-py-wasm/tests_integ/`**: Python integration tests -- **`strandly/`**: Developer CLI tooling for local development workflows (install on PATH via `npm install && npm link -w strandly`, then call `strandly …`) -- **`wit/`**: WebAssembly Interface Type (WIT) definitions defining the contract between the TS SDK and WASM hosts -- **`wit/deps/`**: External WIT dependency interfaces (clocks, io) -- **`dev-docs/`**: Project documentation (testing guidelines, dependency management, divergences, PR guidelines) -- **`.github/workflows/`**: CI/CD automation and quality gates - -**IMPORTANT**: After making changes that affect the directory structure (adding new directories, moving files, or adding significant new files), you MUST update this directory structure section to reflect the current state of the repository. - -## Development Workflow for Agents - -### 1. Environment Setup - -See [CONTRIBUTING.md - Development Environment](CONTRIBUTING.md#development-environment) for: - -- Prerequisites (Node.js 20+, npm) -- Installation steps -- Verification commands - -### 2. Making Changes - -1. **Create feature branch**: `git checkout -b agent-tasks/{ISSUE_NUMBER}` -2. **Implement changes** following the patterns below -3. **Run quality checks** before committing (pre-commit hooks will run automatically) -4. **Commit with conventional commits**: `feat:`, `fix:`, `refactor:`, `docs:`, etc. -5. **Push to remote**: `git push origin agent-tasks/{ISSUE_NUMBER}` -6. **Create pull request** following [PR.md](dev-docs/PR.md) guidelines - -### 3. Pull Request Guidelines - -When creating pull requests, you **MUST** follow the guidelines in [PR.md](dev-docs/PR.md). Key principles: - -- **Focus on WHY**: Explain motivation and user impact, not implementation details -- **Document public API changes**: Show before/after code examples -- **Be concise**: Use prose over bullet lists; avoid exhaustive checklists -- **Target senior engineers**: Assume familiarity with the SDK -- **Exclude implementation details**: Leave these to code comments and diffs - -See [PR.md](dev-docs/PR.md) for the complete guidance and template. - -### 4. Quality Gates - -Pre-commit hooks automatically run: - -- Build (via npm run build, required for workspace type resolution) -- Unit tests with coverage (via npm run test:coverage) -- WASM unit tests (via npm run test -w strands-wasm) -- Linting (via npm run lint) -- Format checking (via npm run format:check) -- Type checking (via npm run type-check) - -All checks must pass before commit is allowed. - -### 5. Testing Guidelines - -When writing tests, you **MUST** follow the guidelines in [dev-docs/TESTING.md](dev-docs/TESTING.md). Key topics covered: - -- Test organization and file location -- Test batching strategy -- Object assertion best practices -- Test coverage requirements -- Multi-environment testing (Node.js and browser) - -See [TESTING.md](dev-docs/TESTING.md) for the complete testing reference. - -## Coding Patterns and Best Practices - -### Logging Style Guide - -The SDK uses a structured logging format consistent with the Python SDK for better log parsing and searchability. - -**Format**: - -```typescript -// With context fields -logger.warn(`field1=<${value1}>, field2=<${value2}> | human readable message`) - -// Without context fields -logger.warn('human readable message') - -// Multiple statements in message (use pipe to separate) -logger.warn(`field=<${value}> | statement one | statement two`) -``` - -**Guidelines**: - -1. **Context Fields** (when relevant): - - Add context as `field=` pairs at the beginning - - Use commas to separate pairs - - Enclose values in `<>` for readability (especially helpful for empty values: `field=<>`) - - Use template literals for string interpolation - -2. **Messages**: - - Add human-readable messages after context fields - - Use lowercase for consistency - - Avoid punctuation (periods, exclamation points) to reduce clutter - - Keep messages concise and focused on a single statement - - If multiple statements are needed, separate them with pipe character (`|`) - -**Examples**: - -```typescript -// Good: Context fields with message -logger.warn(`stop_reason=<${stopReason}>, fallback=<${fallback}> | unknown stop reason, converting to camelCase`) -logger.warn(`event_type=<${eventType}> | unsupported bedrock event type`) - -// Good: Simple message without context fields -logger.warn('cache points are not supported in openai system prompts, ignoring cache points') - -// Good: Multiple statements separated by pipes -logger.warn(`request_id=<${id}> | processing request | starting validation`) - -// Bad: Not using angle brackets for values -logger.warn(`stop_reason=${stopReason} | unknown stop reason`) - -// Bad: Using punctuation -logger.warn(`event_type=<${eventType}> | Unsupported event type.`) -``` - -### Import Organization - -Use relative imports for internal modules: - -```typescript -// Good: Relative imports for internal modules -import { hello } from './hello' -import { Agent } from '../agent' - -// Good: External dependencies -import { something } from 'external-package' -``` - -### File Organization Pattern - -**For source files**: - -``` -strands-ts/src/ -├── module.ts # Source file -└── __tests__/ - └── module.test.ts # Unit tests co-located -``` - -**Function ordering within files**: - -- Functions MUST be ordered from most general to most specific (top-down reading) -- Public/exported functions MUST appear before private helper functions -- Main entry point functions MUST be at the top of the file -- Helper functions SHOULD follow in order of their usage - -**Example**: - -```typescript -// Good: Main function first, helpers follow -export async function* mainFunction() { - const result = await helperFunction1() - return helperFunction2(result) -} - -async function helperFunction1() { - // Implementation -} - -function helperFunction2(input: string) { - // Implementation -} - -// Bad: Helpers before main function -async function helperFunction1() { - // Implementation -} - -export async function* mainFunction() { - const result = await helperFunction1() - return helperFunction2(result) -} -``` - -**For integration tests**: - -``` -strands-ts/test/integ/ -└── feature.test.ts # Tests public API -``` - -### TypeScript Type Safety - -**Optional chaining for null safety**: Prefer optional chaining over verbose `typeof` checks when accessing potentially undefined properties: - -```typescript -// Good: Optional chaining -return globalThis?.process?.env?.API_KEY - -// Bad: Verbose typeof checks -if (typeof process !== 'undefined' && typeof process.env !== 'undefined') { - return process.env.API_KEY -} -return undefined -``` - -**Strict requirements**: - -```typescript -// Good: Explicit return types -export function process(input: string): string { - return input.toUpperCase() -} - -// Bad: No return type -export function process(input: string) { - return input.toUpperCase() -} - -// Good: Proper typing -export function getData(): { id: number; name: string } { - return { id: 1, name: 'test' } -} - -// Bad: Using any -export function getData(): any { - return { id: 1, name: 'test' } -} -``` - -**Rules**: - -- Always provide explicit return types -- Never use `any` type (enforced by ESLint) -- Use TypeScript strict mode features -- Leverage type inference where appropriate - -### Class Field Naming Conventions - -**Private fields**: Use underscore prefix for private class fields to improve readability and distinguish them from public members. - -```typescript -// Good: Private fields with underscore prefix -export class Example { - private readonly _config: Config - private _state: State - - constructor(config: Config) { - this._config = config - this._state = { initialized: false } - } - - public getConfig(): Config { - return this._config - } -} - -// Bad: No underscore for private fields -export class Example { - private readonly config: Config // Missing underscore - - constructor(config: Config) { - this.config = config - } -} -``` - -**Rules**: - -- Private fields MUST use underscore prefix (e.g., `_field`) -- Public fields MUST NOT use underscore prefix -- This convention improves code readability and makes the distinction between public and private members immediately visible - -#### Naming Conventions for New Features - -When choosing names and constants that match an existing implementation in the Python SDK, use exactly the same literal used -in the Python SDK. Wherever we can achieve compatibility, keep the previous convention. - -#### Plugin Naming - -Name plugins for what they do, not for the `Plugin` interface they implement. - -```typescript -// Good -export class AgentSkills implements Plugin { ... } -export class DefaultModelRetryStrategy implements Plugin { ... } - -// Bad -export class AgentSkillsPlugin implements Plugin { ... } -export class DefaultModelRetryStrategyPlugin implements Plugin { ... } ``` - -Same rule for the associated config (`AgentSkillsConfig`, not `AgentSkillsPluginConfig`). - -### Documentation Requirements - -**TSDoc format** (required for all exported functions): - -````typescript -/** - * Brief description of what the function does. - * - * @param paramName - Description of the parameter - * @param optionalParam - Description of optional parameter - * @returns Description of what is returned - * - * @example - * ```typescript - * const result = functionName('input') - * console.log(result) // "output" - * ``` - */ -export function functionName(paramName: string, optionalParam?: number): string { - // Implementation -} -```` - -**Interface property documentation**: - -```typescript -/** - * Interface description. - */ -export interface MyConfig { - /** - * Single-line description of the property. - */ - propertyName: string - - /** - * Single-line description with optional reference link. - * @see https://docs.example.com/property-details - */ - anotherProperty?: number -} +strands-agents/ +├── strands-py/ # Python SDK (hatch) — see strands-py/AGENTS.md +├── strands-ts/ # TypeScript SDK (npm workspace) — see strands-ts/AGENTS.md +├── strands-wasm/ # WASM bindings +├── strands-py-wasm/ # Python ↔ WASM bridge +├── strandly/ # CLI tooling +├── site/ # Documentation site (Astro) — see site/AGENTS.md +├── designs/ # Design proposals +├── dev-docs/ # TypeScript development docs +├── team/ # Team governance (tenets, decisions, API bar-raising) +├── .agents/ # Agent skills and references +├── package.json # npm workspace root +└── .github/workflows/ # CI (ci.yml is the merge gate) ``` -**Requirements**: - -- 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) -- 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 -- TSDoc validation enforced by ESLint - -### Code Style Guidelines - -**Formatting** (enforced by Prettier): - -- No semicolons -- Single quotes -- Line length: 120 characters -- Tab width: 2 spaces -- Trailing commas in ES5 style - -**Example**: - -```typescript -export function example(name: string, options?: Options): Result { - const config = { - name, - enabled: true, - settings: { - timeout: 5000, - retries: 3, - }, - } - - return processConfig(config) -} -``` - -### Import Organization - -Organize imports in this order: - -```typescript -// 1. External dependencies -import { something } from 'external-package' - -// 2. Internal modules (using relative paths) -import { Agent } from '../agent' -import { Tool } from '../tools' - -// 3. Types (if separate) -import type { Options, Config } from '../types' -``` - -### Interface and Type Organization - -**When defining interfaces or types, organize them so the top-level interface comes first, followed by its dependencies, and then all nested dependencies.** - -```typescript -// Correct - Top-level first, then dependencies -export interface Message { - role: Role - content: ContentBlock[] -} - -export type Role = 'user' | 'assistant' - -export type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock - -export class TextBlock { - readonly type = 'textBlock' as const - readonly text: string - constructor(data: { text: string }) { - this.text = data.text - } -} - -export class ToolUseBlock { - readonly type = 'toolUseBlock' as const - readonly name: string - readonly toolUseId: string - readonly input: JSONValue - constructor(data: { name: string; toolUseId: string; input: JSONValue }) { - this.name = data.name - this.toolUseId = data.toolUseId - this.input = data.input - } -} - -export class ToolResultBlock { - readonly type = 'toolResultBlock' as const - readonly toolUseId: string - readonly status: 'success' | 'error' - readonly content: ToolResultContent[] - constructor(data: { toolUseId: string; status: 'success' | 'error'; content: ToolResultContent[] }) { - this.toolUseId = data.toolUseId - this.status = data.status - this.content = data.content - } -} - -// Wrong - Dependencies before top-level -export type Role = 'user' | 'assistant' - -export interface TextBlockData { - text: string -} - -export interface Message { - // Top-level should come first - role: Role - content: ContentBlock[] -} -``` - -**Rationale**: This ordering makes files more readable by providing an overview first, then details. - -### Discriminated Union Naming Convention - -**When creating discriminated unions with a `type` field, the type value MUST match the interface name with the first letter lowercase.** - -```typescript -// Correct - type matches class name (first letter lowercase) -export class TextBlock { - readonly type = 'textBlock' as const // Matches 'TextBlock' class name - readonly text: string - constructor(data: { text: string }) { - this.text = data.text - } -} - -export class CachePointBlock { - readonly type = 'cachePointBlock' as const // Matches 'CachePointBlock' class name - readonly cacheType: 'default' - constructor(data: { cacheType: 'default' }) { - this.cacheType = data.cacheType - } -} - -export type ContentBlock = TextBlock | ToolUseBlock | CachePointBlock - -// Wrong - type doesn't match class name -export class CachePointBlock { - readonly type = 'cachePoint' as const // Should be 'cachePointBlock' - readonly cacheType: 'default' -} -``` - -**Rationale**: This consistent naming makes discriminated unions predictable and improves code readability. Developers can easily understand the relationship between the type value and the class. - -### API Union Types (Bedrock Pattern) - -When the upstream API (e.g., Bedrock) defines a type as a **UNION** ("only one member can be specified"), model it as a TypeScript `type` union with each variant's field **required** — not an `interface` with optional fields. This allows non-breaking expansion when new variants are added. - -The Bedrock API marks all fields in union types as "Not Required" as a mechanism for future extensibility. In TypeScript, encode the mutual exclusivity using `|` with each variant having its field required. The "not required" from the API docs means "this field won't be present if a different variant is active." - -```typescript -// Correct: type union — each variant has its field required -// Adding a new variant later (e.g., | { image: ImageData }) is non-breaking -export type CitationSourceContent = { text: string } - -// Correct: multi-variant union with object-key discrimination -export type DocumentSourceData = - | { bytes: Uint8Array } - | { text: string } - | { content: DocumentContentBlockData[] } - | { location: S3LocationData } - -// Correct: multi-variant union for citation locations -export type CitationLocation = - | { documentChar: DocumentCharLocation } - | { documentPage: DocumentPageLocation } - | { web: WebLocation } - -// Wrong: interface with optional fields — cannot expand without breaking -export interface CitationSourceContent { - text?: string -} - -// Wrong: interface with required field — changing to union later is breaking -export interface CitationSourceContent { - text: string -} -``` - -**Key points**: - -- Use `type` alias (not `interface`) so it can be expanded to a union later -- Each variant's field is **required** within that variant -- Use object-key discrimination (`'text' in source`) to narrow variants at runtime -- See `DocumentSourceData` in `strands-ts/src/types/media.ts` and `CitationLocation` in `strands-ts/src/types/citations.ts` for reference implementations - -### Error Handling - -```typescript -// Good: Explicit error handling -export function process(input: string): string { - if (!input) { - throw new Error('Input cannot be empty') - } - return input.trim() -} - -// Good: Custom error types -export class ValidationError extends Error { - constructor(message: string) { - super(message) - this.name = 'ValidationError' - } -} -``` - -**Key Features:** - -- Automatic tool discovery and registration -- Lazy connection (connects on first use) -- Supports stdio and HTTP transports -- Resource cleanup with `Symbol.dispose` - -**See [`examples/mcp/`](strands-ts/examples/mcp/) for complete working examples.** - -### Test Assertions - -When asserting on objects, prefer `toStrictEqual` for full object comparison rather than checking individual fields: - -```typescript -// Good: Full object assertion with toStrictEqual -expect(provider.getConfig()).toStrictEqual({ - modelId: 'gemini-2.5-flash', - params: { temperature: 0.5 }, -}) - -// Bad: Checking individual fields -expect(provider.getConfig().modelId).toBe('gemini-2.5-flash') -expect(provider.getConfig().params.temperature).toBe(0.5) -``` - -**Rationale**: Full object assertions catch unexpected properties and ensure the complete shape is correct. - -### Dependency Management - -When adding or modifying dependencies, you **MUST** follow the guidelines in [dev-docs/DEPENDENCIES.md](dev-docs/DEPENDENCIES.md). Key points: - -- **`dependencies`**: Core SDK functionality that users don't interact with directly -- **`peerDependencies`**: Dependencies that cross API boundaries (users construct/pass instances) -- **`devDependencies`**: Build tools, testing frameworks, linters - not shipped to users - -**Rule**: If a dependency crosses an API boundary, it **MUST** be a peer dependency. - -## Things to Do - -**Do**: - -- Use relative imports for internal modules -- Co-locate unit tests with source under `__tests__` directories -- Follow nested describe pattern for test organization -- Write explicit return types for all functions -- Document all exported functions with TSDoc -- Use meaningful variable and function names -- Keep functions small and focused (single responsibility) -- Use async/await for asynchronous operations -- Handle errors explicitly - -## Things NOT to Do - -**Don't**: - -- Use `any` type (enforced by ESLint) -- Put unit tests in separate `tests/` directory (use `strands-ts/src/**/__tests__/**`) -- Skip documentation for exported functions -- Use semicolons (Prettier will remove them) -- Commit without running pre-commit hooks -- Ignore linting errors -- Skip type checking -- Use implicit return types - -## Development Commands - -For detailed command usage, see [CONTRIBUTING.md - Testing Instructions](CONTRIBUTING.md#testing-instructions-and-best-practices). - -Quick reference: - -```bash -npm test # Run unit tests in Node.js -npm run test:browser # Run unit tests in browser (Chromium via Playwright) -npm run test:all # Run all tests in all environments -npm run test:integ # Run integration tests -npm run test:coverage # Run tests with coverage report -npm run lint # Check code quality -npm run format # Auto-fix formatting -npm run type-check # Verify TypeScript types -npm run build # Compile TypeScript -``` - -## Troubleshooting Common Issues - -If TypeScript compilation fails: - -1. Run `npm run type-check` to see all type errors -2. Ensure all functions have explicit return types -3. Verify no `any` types are used -4. Check that all imports are correctly typed - -## Agent-Specific Notes - -### When Implementing Features - -1. **Read task requirements** carefully from the GitHub issue -2. **Follow TDD approach** if appropriate: - - Write failing tests first - - Implement minimal code to pass tests - - Refactor while keeping tests green -3. **Use existing patterns** as reference -4. **Document as you go** with TSDoc comments -5. **Run all checks** before committing (pre-commit hooks will enforce this) - -### Writing code - -- YOU MUST make the SMALLEST reasonable changes to achieve the desired outcome. -- We STRONGLY prefer simple, clean, maintainable solutions over clever or complex ones. Readability and maintainability are PRIMARY CONCERNS, even at the cost of conciseness or performance. -- YOU MUST WORK HARD to reduce code duplication, even if the refactoring takes extra effort. -- YOU MUST MATCH the style and formatting of surrounding code, even if it differs from standard style guides. Consistency within a file trumps external standards. -- YOU MUST NOT manually change whitespace that does not affect execution or output. Otherwise, use a formatting tool. -- Fix broken things immediately when you find them. Don't ask permission to fix bugs. - -#### Code Comments - -- NEVER add comments explaining that something is "improved", "better", "new", "enhanced", or referencing what it used to be -- Comments should explain WHAT the code does or WHY it exists, not how it's better than something else -- YOU MUST NEVER add comments about what used to be there or how something has changed. -- YOU MUST NEVER refer to temporal context in comments (like "recently refactored" "moved") or code. Comments should be evergreen and describe the code as it is. -- YOU MUST NEVER write overly verbose comments. Use concise language. - -### Code Review Considerations - -When responding to PR feedback: - -- Address all review comments -- Test changes thoroughly -- Update documentation if behavior changes -- Maintain test coverage -- Follow conventional commit format for fix commits - -### Integration with Other Files - -- **CONTRIBUTING.md**: Contains testing/setup commands and human contribution guidelines -- **dev-docs/TESTING.md**: Comprehensive testing guidelines (MUST follow when writing tests) -- **dev-docs/PR.md**: Pull request guidelines and template -- **README.md**: Public-facing documentation, links to strandsagents.com -- **package.json**: Root workspace config that delegates to strands-ts -- **strands-ts/package.json**: SDK package config, dependencies, and npm scripts +When working on code, determine which sub-project you're in and follow its conventions: +- **Python SDK**: See `strands-py/AGENTS.md` +- **TypeScript SDK**: See `strands-ts/AGENTS.md` +- **Documentation site**: See `site/AGENTS.md` -## Additional Resources +## Shared Conventions -- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html) -- [Vitest Documentation](https://vitest.dev/) -- [TSDoc Reference](https://tsdoc.org/) -- [Conventional Commits](https://www.conventionalcommits.org/) -- [Strands Agents Documentation](https://strandsagents.com/) +- **Branching**: `git checkout -b agent-tasks/{ISSUE_NUMBER}` +- **Commits**: Use [conventional commits](https://www.conventionalcommits.org/) — `feat:`, `fix:`, `refactor:`, `docs:`, etc. +- **Pull requests**: See PR guidelines ([Python](./strands-py/docs/PR.md), [TypeScript](./dev-docs/PR.md)) +- **CI**: The `ci.yml` merge gate detects which paths changed and runs only relevant checks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d1412ce4c3..96bc1be9a7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,7 +50,17 @@ When proposing solutions or reviewing code, we reference these principles to gui ## Development Environment -This project uses [hatchling](https://hatch.pypa.io/latest/build/#hatchling) as the build backend and [hatch](https://hatch.pypa.io/latest/) for development workflow management. +This is a monorepo containing the Python SDK, TypeScript SDK, and documentation site. Each has its own toolchain: + +| Area | Directory | Toolchain | +|------|-----------|-----------| +| Python SDK | `strands-py/` | hatch | +| TypeScript SDK | `strands-ts/` | npm workspace | +| Docs site | `site/` | Astro (npm) | + +### Python SDK + +The Python SDK uses [hatchling](https://hatch.pypa.io/latest/build/#hatchling) as the build backend and [hatch](https://hatch.pypa.io/latest/) for development workflow management. All `hatch` commands should be run from the `strands-py/` subdirectory (where `pyproject.toml` lives): @@ -131,6 +141,33 @@ If you're using an IDE like VS Code or PyCharm, consider configuring it to use t For additional details on styling, please see our dedicated [Style Guide](./strands-py/docs/STYLE_GUIDE.md). +### TypeScript SDK + +The TypeScript SDK uses an npm workspace rooted at the repository root. + +```bash +npm ci # install dependencies (from repo root) +npm run build # build +npm test # run unit tests +npm run lint # lint +npm run type-check # type checking +``` + +### Documentation Site + +The documentation site uses Astro with the Starlight theme. + +```bash +cd site +npm install +npm run dev # local dev server at http://localhost:4321/ +npm run build # production build +npm run typecheck # type checking +npm run typecheck:snippets # type check code examples +``` + +For docs contribution guidelines, see [site/CONTRIBUTING.md](./site/CONTRIBUTING.md). + ## Contributing via Pull Requests Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: @@ -138,7 +175,7 @@ Contributions via pull requests are much appreciated. Before sending us a pull r 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. -For guidance on writing effective PR descriptions, see our [PR Description Guidelines](./strands-py/docs/PR.md). +For guidance on writing effective PR descriptions, see our PR Description Guidelines ([Python](./strands-py/docs/PR.md), [TypeScript](./dev-docs/PR.md)). To send us a pull request, please: @@ -164,4 +201,4 @@ If you discover a potential security issue in this project we ask that you notif ## Licensing -See the [LICENSE](./LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. +See the [LICENSE.APACHE](./LICENSE.APACHE) and [LICENSE.MIT](./LICENSE.MIT) files for our project's licensing. We will ask you to confirm the licensing of your contribution. diff --git a/README.md b/README.md index a053c4edfa..2479af10b5 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@

DocumentationSamples - ◆ Python SDKToolsAgent BuilderMCP Server @@ -35,6 +34,18 @@ Strands Agents is a simple yet powerful SDK that takes a model-driven approach to building and running AI agents. From simple conversational assistants to complex autonomous workflows, from local development to production deployment, Strands Agents scales with your needs. +This monorepo contains the Python SDK, TypeScript SDK, documentation site, and supporting packages: + +| Directory | Description | +|-----------|-------------| +| `strands-py/` | Python SDK — agent loop, model providers, tools ([PyPI](https://pypi.org/project/strands-agents/)) | +| `strands-ts/` | TypeScript SDK — agent loop, model providers, tools ([npm](https://www.npmjs.com/package/@strands/agent)) | +| `strands-wasm/` | WebAssembly bindings for running Python tools from TypeScript agents | +| `strands-py-wasm/` | Python host for WASM components (bridges WIT interfaces to Python) | +| `strandly/` | Developer CLI for local builds, codegen, and workspace tooling | +| `site/` | Documentation site built with Astro/Starlight ([strandsagents.com](https://strandsagents.com)) | +| `designs/` | Design proposals for significant features (RFC-style) | + ## Feature Overview - **Lightweight & Flexible**: Simple agent loop that just works and is fully customizable @@ -310,8 +321,9 @@ For detailed guidance & examples, explore our documentation: ## Development -Source code lives in the `strands-py/` subdirectory. To develop locally: +Git operations (commits, branches, PRs) are done from the repo root. Each package has its own toolchain: +**Python SDK** (`strands-py/`): ```bash cd strands-py pip install hatch @@ -319,7 +331,19 @@ hatch test # run unit tests hatch fmt # format & lint ``` -Git operations (commits, branches, PRs) are still done from the repo root as normal. +**TypeScript SDK** (`strands-ts/`): +```bash +npm ci # install from repo root +npm run build # build +npm test # run unit tests +``` + +**Documentation site** (`site/`): +```bash +cd site +npm install +npm run dev # local dev server at http://localhost:4321/ +``` ## Contributing ❤️ diff --git a/designs/README.md b/designs/README.md index 58a6780bb1..854bd9e07e 100644 --- a/designs/README.md +++ b/designs/README.md @@ -23,7 +23,7 @@ Skip the design process for bug fixes, small improvements, documentation updates ## How to submit a feature proposal 1. **Check the [roadmap](https://github.com/orgs/strands-agents/projects/8/views/1)** — See if your idea aligns with our direction -2. **Fork the [sdk-python repository](https://github.com/strands-agents/sdk-python)** +2. **Create a branch in this repository** 3. **Create your design** — Add a new file: `designs/NNNN-feature-name.md` using the template below 4. **Submit a pull request** — We'll review and discuss 5. **Iterate based on feedback** — Address comments and questions diff --git a/site/AGENTS.md b/site/AGENTS.md index c9fc0db8e8..4cdc730304 100644 --- a/site/AGENTS.md +++ b/site/AGENTS.md @@ -1,9 +1,9 @@ -# Agent Development Guide - strands-agents/private-docs-staging +# Agent Development Guide - Documentation Site -This document provides guidance specifically for AI agents working on the strands-agents/private-docs-staging codebase. For human contributor guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). +This document provides guidance for AI agents working on the Strands Agents documentation site (the `site/` directory). For human contributor guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). ## Purpose and Scope -The goal of this repository is to revamp this documentation repo so that it provides clear and well organized documentation on how to develop with Strands SDK with either Python or Typescript. +This directory contains the documentation site for Strands Agents, providing guides on how to develop with the SDK in both Python and TypeScript. **AGENTS.md** contains agent-specific repository information including: - Directory structure with summaries of what is included in each directory @@ -17,10 +17,10 @@ The goal of this repository is to revamp this documentation repo so that it prov When working on SDK features or documentation, familiarize yourself with these team processes: -* **[Feature Lifecycle Process](team/FEATURE_LIFECYCLE.md)**: How features are added, versioned, deprecated, and graduated from experimental status -* **[API Bar Raising](team/API_BAR_RAISING.md)**: Standards for API design quality -* **[Decisions](team/DECISIONS.md)**: Key architectural and design decisions -* **[Tenets](team/TENETS.md)**: Core principles guiding SDK development +* **[Feature Lifecycle Process](../team/FEATURE_LIFECYCLE.md)**: How features are added, versioned, deprecated, and graduated from experimental status +* **[API Bar Raising](../team/API_BAR_RAISING.md)**: Standards for API design quality +* **[Decisions](../team/DECISIONS.md)**: Key architectural and design decisions +* **[Tenets](../team/TENETS.md)**: Core principles guiding SDK development These documents define the standards and processes that ensure consistency and quality across the Strands SDK. @@ -212,7 +212,7 @@ import type { Options, Config } from '../types' - [TSDoc Reference](https://tsdoc.org/) - [Conventional Commits](https://www.conventionalcommits.org/) - [Strands Agents Documentation](https://strandsagents.com/) -- [Typescript SDK](https://github.com/strands-agents/sdk-typescript/) +- [TypeScript SDK](../strands-ts/) # TypeScript Code Examples Guide diff --git a/site/CONTRIBUTING.md b/site/CONTRIBUTING.md index 32fddec071..fe162000c6 100644 --- a/site/CONTRIBUTING.md +++ b/site/CONTRIBUTING.md @@ -73,7 +73,7 @@ reported the issue. Please try to include as much information as you can. Detail Looking at the existing issues is a great way to find something to contribute to. We label issues that are well-defined and ready for community contributions with the "ready for contribution" label. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. Check our "Ready for Contribution" issues for items you can work on: -- [SDK Python Issues](https://github.com/strands-agents/sdk-python/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22ready%20for%20contribution%22) +- [SDK Issues](https://github.com/strands-agents/sdk-python/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22ready%20for%20contribution%22) - [Tools Issues](https://github.com/strands-agents/tools/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22ready%20for%20contribution%22) Before starting work on any issue: diff --git a/site/src/content/docs/contribute/contributing/core-sdk.mdx b/site/src/content/docs/contribute/contributing/core-sdk.mdx index efa0d9455d..68c107fe66 100644 --- a/site/src/content/docs/contribute/contributing/core-sdk.mdx +++ b/site/src/content/docs/contribute/contributing/core-sdk.mdx @@ -12,8 +12,7 @@ This guide walks you through contributing to sdk-python and sdk-typescript. We'l Looking for a place to start? Check our issues labeled "ready for contribution"—these are well-defined and ready for community work. -- [Python SDK issues](https://github.com/strands-agents/sdk-python/issues?q=is%3Aissue+state%3Aopen+label%3A%22ready+for+contribution%22) -- [TypeScript SDK issues](https://github.com/strands-agents/sdk-typescript/issues?q=is%3Aissue+state%3Aopen+label%3A%22ready+for+contribution%22) +- [SDK issues](https://github.com/strands-agents/sdk-python/issues?q=is%3Aissue+state%3Aopen+label%3A%22ready+for+contribution%22) Before starting work on any issue, check if someone is already assigned or working on it. @@ -50,7 +49,7 @@ First, we'll clone the repository and set up the virtual environment. ```bash git clone https://github.com/strands-agents/sdk-python.git -cd sdk-python +cd sdk-python/strands-py ``` We use [hatch](https://hatch.pypa.io/) for Python development. Hatch manages virtual environments, dependencies, testing, and formatting. Enter the virtual environment and install pre-commit hooks. @@ -86,15 +85,15 @@ hatch run prepare # Run all checks before committing - Use `hatch run test-integ` to run integration tests with real model providers - Run `hatch test --all` to test across Python 3.10-3.13 -- Check [CONTRIBUTING.md](https://github.com/strands-agents/sdk-python/blob/main/CONTRIBUTING.md) for detailed development workflow +- Check [CONTRIBUTING.md](https://github.com/strands-agents/sdk-python/blob/main/CONTRIBUTING.md) for the full development workflow First, we'll clone the repository and install dependencies. ```bash -git clone https://github.com/strands-agents/sdk-typescript.git -cd sdk-typescript +git clone https://github.com/strands-agents/sdk-python.git +cd sdk-python npm install ``` @@ -122,7 +121,7 @@ npm run format # Format code with Prettier - Use `npm run test:integ` to run integration tests - Run `npm run test:all` to test in both Node.js and browser environments -- Check [CONTRIBUTING.md](https://github.com/strands-agents/sdk-typescript/blob/main/CONTRIBUTING.md) for detailed requirements +- Check [CONTRIBUTING.md](https://github.com/strands-agents/sdk-python/blob/main/CONTRIBUTING.md) for the full development workflow @@ -144,4 +143,4 @@ The pre-commit hooks help catch issues before you push, but you can also run che ## Related guides - [Feature proposals](./feature-proposals.md) — For significant features requiring discussion -- [Team documentation](https://github.com/strands-agents/docs/tree/main/team) — Our tenets, decisions, and API review process +- [Team documentation](https://github.com/strands-agents/sdk-python/tree/main/team) — Our tenets, decisions, and API review process diff --git a/site/src/content/docs/contribute/contributing/documentation.mdx b/site/src/content/docs/contribute/contributing/documentation.mdx index e073eed6d4..862592390b 100644 --- a/site/src/content/docs/contribute/contributing/documentation.mdx +++ b/site/src/content/docs/contribute/contributing/documentation.mdx @@ -4,7 +4,7 @@ sidebar: label: "Documentation" --- -Good documentation helps developers succeed with Strands. We welcome contributions that make our docs clearer, more complete, or more helpful. Our documentation lives in the [docs repository](https://github.com/strands-agents/docs). +Good documentation helps developers succeed with Strands. We welcome contributions that make our docs clearer, more complete, or more helpful. Our documentation lives in the `site/` directory of the [Strands SDK repository](https://github.com/strands-agents/sdk-python). ## What we accept @@ -23,9 +23,9 @@ We're looking for contributions that improve the developer experience. Documenta Let's get the docs running locally so you can preview your changes as you work. The docs are built with [Astro](https://astro.build/) and the [Starlight](https://starlight.astro.build/) theme. ```bash -# Clone the docs repository -git clone https://github.com/strands-agents/docs.git -cd docs +# Clone the repository +git clone https://github.com/strands-agents/sdk-python.git +cd sdk-python/site # Install dependencies npm install @@ -42,7 +42,7 @@ The development server automatically reloads when you save changes, so you can s The submission process varies based on the size of your change. Small fixes can go straight to PR, while larger changes benefit from discussion first. -1. **Fork the docs repository** on GitHub +1. **Fork the repository** on GitHub 2. **Create a branch** with a descriptive name like `docs/clarify-tools-usage` or `docs/fix-typo-agent-loop` 3. **Make your changes** in your favorite editor 4. **Preview locally** with `npm run dev` to verify formatting and links work correctly diff --git a/site/src/content/docs/contribute/contributing/feature-proposals.mdx b/site/src/content/docs/contribute/contributing/feature-proposals.mdx index ffd03cc555..495e072bfd 100644 --- a/site/src/content/docs/contribute/contributing/feature-proposals.mdx +++ b/site/src/content/docs/contribute/contributing/feature-proposals.mdx @@ -32,7 +32,7 @@ The design document process helps align on requirements, explore alternatives, a 1. **Check the [roadmap](https://github.com/orgs/strands-agents/projects/8/views/1)** — See if your idea aligns with our direction and isn't already planned 2. **Open an issue first** — Describe the problem you're trying to solve. We need to validate the problem is worth solving before you invest time in a detailed proposal -3. **Create a design document** — Once we agree the problem is worth solving, submit a PR to the [`designs` folder](https://github.com/strands-agents/docs/tree/main/designs) in the docs repository using the template there. Reference the issue in your design document +3. **Create a design document** — Once we agree the problem is worth solving, submit a PR to the [`designs` folder](https://github.com/strands-agents/sdk-python/tree/main/designs) using the template there. Reference the issue in your design document 4. **Gather feedback** — We'll review and discuss with you, asking clarifying questions 5. **Get approval** — When we merge the design document, that's your go-ahead to implement 6. **Implement** — Follow the [SDK contribution process](./core-sdk.md) @@ -40,11 +40,11 @@ The design document process helps align on requirements, explore alternatives, a ## Design document template -See the full template in the [designs folder README](https://github.com/strands-agents/docs/blob/main/designs/README.md#design-document-template). +See the full template in the [designs folder README](https://github.com/strands-agents/sdk-python/blob/main/designs/README.md#design-document-template). **Tips for effective proposals:** - Focus on the problem first, solution comes second - Include concrete examples showing current pain and proposed improvement - Be open to feedback, the best solution might differ from your initial idea -- Align with our [development tenets](https://github.com/strands-agents/docs/blob/main/team/TENETS.md) +- Align with our [development tenets](https://github.com/strands-agents/sdk-python/blob/main/team/TENETS.md) diff --git a/strands-py-wasm/pyproject.toml b/strands-py-wasm/pyproject.toml index f2a025cd2b..f2c9ba610c 100644 --- a/strands-py-wasm/pyproject.toml +++ b/strands-py-wasm/pyproject.toml @@ -38,8 +38,8 @@ pydantic = ["pydantic>=2.4.0,<3.0.0"] [project.urls] -Homepage = "https://github.com/strands-agents/sdk-typescript" -"Bug Tracker" = "https://github.com/strands-agents/sdk-typescript/issues" +Homepage = "https://github.com/strands-agents/sdk-python" +"Bug Tracker" = "https://github.com/strands-agents/sdk-python/issues" Documentation = "https://strandsagents.com" diff --git a/strands-py/AGENTS.md b/strands-py/AGENTS.md index 8a3973fa29..75048ddab4 100644 --- a/strands-py/AGENTS.md +++ b/strands-py/AGENTS.md @@ -19,226 +19,22 @@ Strands Agents is an open-source Python SDK for building AI agents with a model- ## Directory Structure ``` -strands-agents/ -│ -├── src/strands/ # Main package source code -│ ├── agent/ # Core agent implementation -│ │ ├── agent.py # Main Agent class -│ │ ├── agent_result.py # Agent execution results -│ │ ├── base.py # AgentBase protocol (agent interface) -│ │ ├── a2a_agent.py # A2AAgent client for remote A2A agents -│ │ ├── state.py # Agent state management -│ │ └── conversation_manager/ # Message history strategies -│ │ ├── conversation_manager.py # Base conversation manager -│ │ ├── null_conversation_manager.py # No-op manager -│ │ ├── sliding_window_conversation_manager.py # Window-based -│ │ └── summarizing_conversation_manager.py # Summarization-based -│ │ -│ ├── event_loop/ # Agent execution loop -│ │ ├── event_loop.py # Main loop logic -│ │ ├── streaming.py # Streaming response handling -│ │ └── _recover_message_on_max_tokens_reached.py -│ │ -│ ├── models/ # Model provider implementations -│ │ ├── model.py # Base model interface -│ │ ├── bedrock.py # Amazon Bedrock -│ │ ├── anthropic.py # Anthropic Claude -│ │ ├── openai.py # OpenAI -│ │ ├── gemini.py # Google Gemini -│ │ ├── ollama.py # Ollama local models -│ │ ├── litellm.py # LiteLLM unified interface -│ │ ├── mistral.py # Mistral AI -│ │ ├── llamaapi.py # LlamaAPI -│ │ ├── llamacpp.py # llama.cpp local -│ │ ├── sagemaker.py # AWS SageMaker -│ │ ├── writer.py # Writer AI -│ │ └── _validation.py # Validation utilities -│ │ -│ ├── tools/ # Tool system -│ │ ├── decorator.py # @tool decorator -│ │ ├── tools.py # Tool base classes -│ │ ├── tool_provider.py # ToolProvider interface -│ │ ├── registry.py # Tool registration -│ │ ├── loader.py # Dynamic tool loading -│ │ ├── watcher.py # Hot reload -│ │ ├── _caller.py # Tool invocation -│ │ ├── _validator.py # Tool validation -│ │ ├── _tool_helpers.py # Helper utilities -│ │ ├── executors/ # Tool execution environments -│ │ │ ├── _executor.py # Base executor -│ │ │ ├── concurrent.py # Thread/process pool -│ │ │ └── sequential.py # Sequential execution -│ │ ├── mcp/ # Model Context Protocol -│ │ │ ├── mcp_client.py # MCP client implementation -│ │ │ ├── mcp_agent_tool.py # MCP tool wrapper -│ │ │ ├── mcp_types.py # MCP type definitions -│ │ │ ├── mcp_tasks.py # Task-augmented execution config -│ │ │ └── mcp_instrumentation.py # MCP telemetry -│ │ └── structured_output/ # Structured output handling -│ │ ├── structured_output_tool.py -│ │ ├── structured_output_utils.py -│ │ └── _structured_output_context.py -│ │ -│ ├── multiagent/ # Multi-agent patterns -│ │ ├── base.py # Base multi-agent classes -│ │ ├── graph.py # Graph-based orchestration -│ │ ├── swarm.py # Swarm pattern -│ │ ├── a2a/ # Agent-to-agent protocol -│ │ │ ├── executor.py # A2A executor -│ │ │ ├── server.py # A2A server -│ │ │ └── converters.py # Strands/A2A type converters -│ │ └── nodes/ # Graph node implementations -│ │ -│ ├── types/ # Type definitions -│ │ ├── content.py # Content types (text, images, etc.) -│ │ ├── tools.py # Tool-related types -│ │ ├── streaming.py # Streaming event types -│ │ ├── exceptions.py # Custom exceptions -│ │ ├── agent.py # Agent types -│ │ ├── session.py # Session types -│ │ ├── multiagent.py # Multi-agent types -│ │ ├── guardrails.py # Guardrail types -│ │ ├── interrupt.py # Interrupt types -│ │ ├── media.py # Media types -│ │ ├── citations.py # Citation types -│ │ ├── traces.py # Trace types -│ │ ├── event_loop.py # Event loop types -│ │ ├── json_dict.py # JSON dict utilities -│ │ ├── collections.py # Collection types -│ │ ├── _snapshot.py # Snapshot types and helpers -│ │ ├── _events.py # Internal event types -│ │ ├── a2a.py # A2A protocol types -│ │ └── models/ # Model-specific types -│ │ -│ ├── session/ # Session management -│ │ ├── session_manager.py # Base interface -│ │ ├── file_session_manager.py # File-based storage -│ │ ├── s3_session_manager.py # S3 storage -│ │ ├── repository_session_manager.py # Repository pattern -│ │ └── session_repository.py # Storage interface -│ │ -│ ├── telemetry/ # Observability (OpenTelemetry) -│ │ ├── tracer.py # Tracing -│ │ ├── metrics.py # Metrics collection -│ │ ├── metrics_constants.py # Metric definitions -│ │ └── config.py # Configuration -│ │ -│ ├── hooks/ # Event hooks system -│ │ ├── events.py # Hook event definitions -│ │ ├── registry.py # Hook registration -│ │ └── _type_inference.py # Event type inference from type hints -│ │ -│ ├── plugins/ # Plugin system -│ │ ├── plugin.py # Plugin base class -│ │ ├── multiagent_plugin.py # MultiAgentPlugin base class -│ │ ├── decorator.py # @hook decorator -│ │ ├── registry.py # PluginRegistry for tracking agent plugins -│ │ ├── multiagent_registry.py # Registry for tracking orchestrator plugins -│ │ └── _discovery.py # Shared hook/tool discovery utilities -│ │ -│ ├── handlers/ # Event handlers -│ │ └── callback_handler.py # Callback handling -│ │ -│ ├── vended_plugins/ # Production plugin implementations -│ │ ├── steering/ # Agent steering system -│ │ │ ├── context_providers/ # Context data providers (e.g., ledger) -│ │ │ ├── core/ # Base classes, actions, context -│ │ │ └── handlers/ # Handler implementations (e.g., LLM) -│ │ ├── skills/ # AgentSkills.io integration (Skill, AgentSkills) -│ │ └── context_offloader/ # Large tool result offloading plugin -│ │ -│ ├── experimental/ # Experimental features (API may change) -│ │ ├── agent_config.py # Experimental agent config -│ │ ├── bidi/ # Bidirectional streaming -│ │ │ ├── agent/ # Bidi agent implementation -│ │ │ ├── io/ # Input/output handling -│ │ │ ├── models/ # Bidi model providers -│ │ │ ├── tools/ # Bidi tools -│ │ │ ├── types/ # Bidi types -│ │ │ └── _async/ # Async utilities -│ │ ├── checkpoint/ # Durable agent execution checkpoints -│ │ │ └── checkpoint.py # Checkpoint dataclass and serialization -│ │ ├── hooks/ # Experimental hooks -│ │ │ ├── events.py -│ │ │ └── multiagent/ -│ │ ├── steering/ # Deprecated aliases for vended_plugins/steering -│ │ └── tools/ # Deprecated aliases for strands.tools -│ │ -│ ├── __init__.py # Public API exports -│ ├── interrupt.py # Interrupt handling -│ ├── _async.py # Async utilities -│ ├── _exception_notes.py # Exception helpers -│ ├── _identifier.py # ID generation -│ └── py.typed # PEP 561 marker -│ -├── tests/ # Unit tests (mirrors src/) -│ ├── conftest.py # Pytest fixtures -│ ├── fixtures/ # Test fixtures -│ │ ├── mocked_model_provider.py # Mock model for testing -│ │ ├── mock_agent_tool.py -│ │ ├── mock_hook_provider.py -│ │ └── ... -│ └── strands/ # Tests mirror src/strands/ -│ ├── agent/ -│ ├── event_loop/ -│ ├── models/ -│ ├── tools/ -│ ├── multiagent/ -│ ├── types/ -│ ├── session/ -│ ├── telemetry/ -│ ├── hooks/ -│ ├── plugins/ -│ ├── handlers/ -│ ├── experimental/ -│ └── utils/ -│ -├── tests_integ/ # Integration tests -│ ├── conftest.py -│ ├── models/ # Model provider tests -│ │ ├── test_model_bedrock.py -│ │ ├── test_model_anthropic.py -│ │ ├── test_model_openai.py -│ │ ├── test_model_gemini.py -│ │ ├── test_model_ollama.py -│ │ └── ... -│ ├── mcp/ # MCP integration tests -│ │ ├── test_mcp_client.py -│ │ ├── echo_server.py -│ │ └── ... -│ ├── tools/ # Tool system tests -│ ├── hooks/ # Hook tests -│ ├── interrupts/ # Interrupt tests -│ ├── steering/ # Steering tests -│ ├── bidi/ # Bidirectional streaming tests -│ ├── a2a/ # A2A agent integration tests -│ ├── test_multiagent_graph.py -│ ├── test_multiagent_swarm.py -│ ├── test_stream_agent.py -│ ├── test_session.py -│ └── ... -│ -├── docs/ # Developer documentation -│ ├── README.md # Docs folder overview -│ ├── STYLE_GUIDE.md # Code style conventions -│ ├── HOOKS.md # Hooks system guide -│ ├── PR.md # PR description guidelines -│ └── MCP_CLIENT_ARCHITECTURE.md # MCP threading architecture -│ -├── pyproject.toml # Project config (build, deps, tools) -├── AGENTS.md # This file -└── CONTRIBUTING.md # Human contributor guidelines +strands-py/ +├── src/strands/ # All production source code +│ ├── agent/ # Core agent loop, state, conversation management +│ ├── models/ # Model provider implementations (Bedrock, OpenAI, etc.) +│ ├── tools/ # Tool system (registry, execution, MCP client) +│ ├── event_loop/ # Event loop and streaming +│ ├── multiagent/ # Multi-agent orchestration (A2A, graphs, swarm) +│ ├── session/ # Session persistence +│ ├── telemetry/ # Tracing and metrics +│ └── types/ # Shared type definitions +├── tests/ # Unit tests (mirrors src/ structure) +├── tests_integ/ # Integration tests with real providers +├── docs/ # Developer documentation +└── pyproject.toml # Build config, dependencies, tool settings ``` -### Directory Purposes - -- **`src/strands/`**: All production code -- **`tests/`**: Unit tests mirroring src/ structure -- **`tests_integ/`**: Integration tests with real model providers -- **`docs/`**: Developer documentation for contributors - -**IMPORTANT**: After making changes that affect the directory structure (adding new directories, moving files, or adding significant new files), you MUST update this directory structure section to reflect the current state of the repository. - ## Development Workflow ### 1. Environment Setup diff --git a/strands-ts/AGENTS.md b/strands-ts/AGENTS.md new file mode 100644 index 0000000000..81637d85eb --- /dev/null +++ b/strands-ts/AGENTS.md @@ -0,0 +1,311 @@ +# Agent Development Guide - TypeScript SDK + +This document provides guidance for AI agents working on the Strands TypeScript SDK (`strands-ts/`). For human contributor guidelines, see [CONTRIBUTING.md](../CONTRIBUTING.md). + +## Development Workflow + +### 1. Environment Setup + +See [CONTRIBUTING.md - TypeScript SDK](../CONTRIBUTING.md#typescript-sdk) for: + +- Prerequisites (Node.js 20+, npm) +- Installation steps +- Verification commands + +### 2. Making Changes + +1. **Create feature branch**: `git checkout -b agent-tasks/{ISSUE_NUMBER}` +2. **Implement changes** following the patterns below +3. **Run quality checks** before committing (pre-commit hooks will run automatically) +4. **Commit with conventional commits**: `feat:`, `fix:`, `refactor:`, `docs:`, etc. +5. **Push to remote**: `git push origin agent-tasks/{ISSUE_NUMBER}` +6. **Create pull request** following [PR.md](../dev-docs/PR.md) guidelines + +### 3. Pull Request Guidelines + +When creating pull requests, you **MUST** follow the guidelines in [PR.md](../dev-docs/PR.md) and use the [PR template](../.github/PULL_REQUEST_TEMPLATE.md). Key principles: + +- **Focus on WHY**: Explain motivation and user impact, not implementation details +- **Document public API changes**: Show before/after code examples +- **Be concise**: Use prose over bullet lists; avoid exhaustive checklists +- **Target senior engineers**: Assume familiarity with the SDK +- **Exclude implementation details**: Leave these to code comments and diffs + +See [PR.md](../dev-docs/PR.md) for the complete guidance and template. + +### 4. Quality Gates + +Pre-commit hooks automatically run: + +- Build (via npm run build, required for workspace type resolution) +- Unit tests with coverage (via npm run test:coverage) +- WASM unit tests (via npm run test -w strands-wasm) +- Linting (via npm run lint) +- Format checking (via npm run format:check) +- Type checking (via npm run type-check) + +All checks must pass before commit is allowed. + +### 5. Testing Guidelines + +When writing tests, you **MUST** follow the guidelines in [dev-docs/TESTING.md](../dev-docs/TESTING.md). Key topics covered: + +- Test organization and file location +- Test batching strategy +- Object assertion best practices +- Test coverage requirements +- Multi-environment testing (Node.js and browser) + +See [TESTING.md](../dev-docs/TESTING.md) for the complete testing reference. + +## Coding Patterns and Best Practices + +### Logging Style Guide + +The SDK uses a structured logging format consistent with the Python SDK for better log parsing and searchability. + +**Format**: + +```typescript +// With context fields +logger.warn(`field1=<${value1}>, field2=<${value2}> | human readable message`) + +// Without context fields +logger.warn('human readable message') + +// Multiple statements in message (use pipe to separate) +logger.warn(`field=<${value}> | statement one | statement two`) +``` + +**Guidelines**: + +1. **Context Fields** (when relevant): + - Add context as `field=` pairs at the beginning + - Use commas to separate pairs + - Enclose values in `<>` for readability (especially helpful for empty values: `field=<>`) + - Use template literals for string interpolation + +2. **Messages**: + - Add human-readable messages after context fields + - Use lowercase for consistency + - Avoid punctuation (periods, exclamation points) to reduce clutter + - Keep messages concise and focused on a single statement + - If multiple statements are needed, separate them with pipe character (`|`) + +**Examples**: + +```typescript +// Good: Context fields with message +logger.warn(`stop_reason=<${stopReason}>, fallback=<${fallback}> | unknown stop reason, converting to camelCase`) +logger.warn(`event_type=<${eventType}> | unsupported bedrock event type`) + +// Good: Simple message without context fields +logger.warn('cache points are not supported in openai system prompts, ignoring cache points') + +// Good: Multiple statements separated by pipes +logger.warn(`request_id=<${id}> | processing request | starting validation`) + +// Bad: Not using angle brackets for values +logger.warn(`stop_reason=${stopReason} | unknown stop reason`) + +// Bad: Using punctuation +logger.warn(`event_type=<${eventType}> | Unsupported event type.`) +``` + +### Import Organization + +Organize imports in this order: + +```typescript +// 1. External dependencies +import { something } from 'external-package' + +// 2. Internal modules (using relative paths) +import { Agent } from '../agent' +import { Tool } from '../tools' + +// 3. Types (if separate) +import type { Options, Config } from '../types' +``` + +### File Organization Pattern + +**For source files**: + +``` +strands-ts/src/ +├── module.ts # Source file +└── __tests__/ + └── module.test.ts # Unit tests co-located +``` + +**Function ordering within files**: + +- Functions MUST be ordered from most general to most specific (top-down reading) +- Public/exported functions MUST appear before private helper functions +- Main entry point functions MUST be at the top of the file +- Helper functions SHOULD follow in order of their usage + +**For integration tests**: + +``` +strands-ts/test/integ/ +└── feature.test.ts # Tests public API +``` + +### TypeScript Type Safety + +**Optional chaining for null safety**: Prefer optional chaining over verbose `typeof` checks when accessing potentially undefined properties: + +```typescript +// Good: Optional chaining +return globalThis?.process?.env?.API_KEY + +// Bad: Verbose typeof checks +if (typeof process !== 'undefined' && typeof process.env !== 'undefined') { + return process.env.API_KEY +} +return undefined +``` + +**Strict requirements**: + +- Always provide explicit return types +- Never use `any` type (enforced by ESLint) +- Use TypeScript strict mode features +- Leverage type inference where appropriate + +### Class Field Naming Conventions + +**Private fields**: Use underscore prefix for private class fields. + +```typescript +// Good: Private fields with underscore prefix +export class Example { + private readonly _config: Config + private _state: State +} + +// Bad: No underscore for private fields +export class Example { + private readonly config: Config +} +``` + +#### Naming Conventions for New Features + +When choosing names and constants that match an existing implementation in the Python SDK, use exactly the same literal used in the Python SDK. Wherever we can achieve compatibility, keep the previous convention. + +#### Plugin Naming + +Name plugins for what they do, not for the `Plugin` interface they implement. + +```typescript +// Good +export class AgentSkills implements Plugin { ... } +export class DefaultModelRetryStrategy implements Plugin { ... } + +// Bad +export class AgentSkillsPlugin implements Plugin { ... } +``` + +### Documentation Requirements + +**TSDoc format** (required for all exported functions): + +- 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) +- Do NOT include `@example` for type definitions, interfaces, or internal types +- Interface properties MUST have single-line descriptions +- TSDoc validation enforced by ESLint + +### Code Style Guidelines + +**Formatting** (enforced by Prettier): + +- No semicolons +- Single quotes +- Line length: 120 characters +- Tab width: 2 spaces +- Trailing commas in ES5 style + +### Dependency Management + +When adding or modifying dependencies, you **MUST** follow the guidelines in [dev-docs/DEPENDENCIES.md](../dev-docs/DEPENDENCIES.md). Key points: + +- **`dependencies`**: Core SDK functionality that users don't interact with directly +- **`peerDependencies`**: Dependencies that cross API boundaries (users construct/pass instances) +- **`devDependencies`**: Build tools, testing frameworks, linters - not shipped to users + +**Rule**: If a dependency crosses an API boundary, it **MUST** be a peer dependency. + +## Things to Do + +- Use relative imports for internal modules +- Co-locate unit tests with source under `__tests__` directories +- Follow nested describe pattern for test organization +- Write explicit return types for all functions +- Document all exported functions with TSDoc +- Use meaningful variable and function names +- Keep functions small and focused (single responsibility) +- Handle errors explicitly + +## Things NOT to Do + +- Use `any` type (enforced by ESLint) +- Put unit tests in separate `tests/` directory (use `strands-ts/src/**/__tests__/**`) +- Skip documentation for exported functions +- Use semicolons (Prettier will remove them) +- Commit without running pre-commit hooks +- Ignore linting errors +- Use implicit return types + +## Development Commands + +Quick reference: + +```bash +npm test # Run unit tests in Node.js +npm run test:browser # Run unit tests in browser (Chromium via Playwright) +npm run test:all # Run all tests in all environments +npm run test:integ # Run integration tests +npm run test:coverage # Run tests with coverage report +npm run lint # Check code quality +npm run format # Auto-fix formatting +npm run type-check # Verify TypeScript types +npm run build # Compile TypeScript +``` + +## Agent-Specific Notes + +### Writing code + +- YOU MUST make the SMALLEST reasonable changes to achieve the desired outcome. +- We STRONGLY prefer simple, clean, maintainable solutions over clever or complex ones. +- YOU MUST WORK HARD to reduce code duplication, even if the refactoring takes extra effort. +- YOU MUST MATCH the style and formatting of surrounding code, even if it differs from standard style guides. +- Fix broken things immediately when you find them. Don't ask permission to fix bugs. + +#### Code Comments + +- NEVER add comments explaining that something is "improved", "better", "new", "enhanced", or referencing what it used to be +- Comments should explain WHAT the code does or WHY it exists, not how it's better than something else +- Comments should be evergreen — never reference temporal context + +### Integration with Other Files + +- **CONTRIBUTING.md**: Contains testing/setup commands and human contribution guidelines +- **dev-docs/TESTING.md**: Comprehensive testing guidelines (MUST follow when writing tests) +- **dev-docs/PR.md**: Pull request guidelines and template +- **package.json**: Root workspace config that delegates to strands-ts +- **strands-ts/package.json**: SDK package config, dependencies, and npm scripts + +## Additional Resources + +- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html) +- [Vitest Documentation](https://vitest.dev/) +- [TSDoc Reference](https://tsdoc.org/) +- [Conventional Commits](https://www.conventionalcommits.org/) +- [Strands Agents Documentation](https://strandsagents.com/) diff --git a/strands-ts/package.json b/strands-ts/package.json index 4060223f96..b2f49211b9 100644 --- a/strands-ts/package.json +++ b/strands-ts/package.json @@ -177,12 +177,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/strands-agents/sdk-typescript.git" + "url": "git+https://github.com/strands-agents/sdk-python.git" }, "bugs": { - "url": "https://github.com/strands-agents/sdk-typescript/issues" + "url": "https://github.com/strands-agents/sdk-python/issues" }, - "homepage": "https://github.com/strands-agents/sdk-typescript#readme", + "homepage": "https://github.com/strands-agents/sdk-python#readme", "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.1037.0", "@types/json-schema": "^7.0.15", diff --git a/strands-wasm/README.md b/strands-wasm/README.md index 64a32e7e70..681e7e5b90 100644 --- a/strands-wasm/README.md +++ b/strands-wasm/README.md @@ -24,8 +24,8 @@ In WIT terminology, the WASM component is the "guest" and Python is the "host". ### First-time setup ```bash -git clone https://github.com/strands-agents/sdk-typescript.git -cd sdk-typescript +git clone https://github.com/strands-agents/sdk-python.git +cd sdk-python npm install npm run dev -- bootstrap ``` diff --git a/site/team/AGENT_GUIDELINES.md b/team/AGENT_GUIDELINES.md similarity index 100% rename from site/team/AGENT_GUIDELINES.md rename to team/AGENT_GUIDELINES.md diff --git a/site/team/API_BAR_RAISING.md b/team/API_BAR_RAISING.md similarity index 100% rename from site/team/API_BAR_RAISING.md rename to team/API_BAR_RAISING.md diff --git a/site/team/DECISIONS.md b/team/DECISIONS.md similarity index 100% rename from site/team/DECISIONS.md rename to team/DECISIONS.md diff --git a/site/team/FEATURE_LIFECYCLE.md b/team/FEATURE_LIFECYCLE.md similarity index 100% rename from site/team/FEATURE_LIFECYCLE.md rename to team/FEATURE_LIFECYCLE.md diff --git a/site/team/README.md b/team/README.md similarity index 100% rename from site/team/README.md rename to team/README.md diff --git a/site/team/TENETS.md b/team/TENETS.md similarity index 100% rename from site/team/TENETS.md rename to team/TENETS.md