# @cagataycali/strands-tools

**TypeScript/browser tools + React hooks for [Strands Agents](https://github.com/strands-agents/strands-sdk-ts).** Ship agent UIs fast.

The TS/browser counterpart of my [strands-agents/tools](https://github.com/strands-agents/tools) Python package: 30+ drop-in tools and a full `useAgent` / `useAgents` hook set so you can build agent-powered chat UIs in minutes instead of weeks.

## Install

```bash
npm install @cagataycali/strands-tools @strands-agents/sdk zod
# for React hooks:
npm install react idb-keyval
```

## What you get

### 🧰 30+ tools

**Agent self-management**
- `manage_messages` — trim/compact/drop/stats your own context window
- `manage_tools` — enable/disable/list/disable_group tools at runtime
- `self-modify` — agent can `create_tool`, `update_self_prompt`, `add_context`

**Coordination**
- `mesh` — BroadcastChannel cross-tab agent coordination (invoke/broadcast/ring)
- `multi-agent` — spawn/kill/invoke/broadcast to sibling agents in-tab
- `npm` — load ANY npm package via esm.sh from the browser, fallback to WebContainer for Node-only packages

**Browser-native superpowers**
- `dom` — query/mutate/observe the agent's own page
- `webcontainer` — full Node.js runtime in the browser (npm install, dev servers)
- `webgpu` — WGSL compute shaders + image kernels + benchmark
- `network-intercept` — log/block/mock/delay/modify fetch + XHR + WebSocket
- `offscreen-canvas` — render graphics off the main thread (charts, badges, sprite sheets)
- `file-system` — real local disk (File System Access API)
- `virtual-cursor` — visible agent-controlled cursor overlay for demos

**Media & ML**
- `transformers-js` — on-device ML (Whisper, SpeechT5, Moondream, DINOv3, MiniLM, Florence-2, 1200+ models)
- `vision` — screenshot + camera + image analysis
- `streaming-media` — camera/mic/screen → Transformers.js with UI overlay
- `audio` — speech synthesis + recognition
- `openai-image` — DALL-E / gpt-image-1
- `qr` — generate + scan QR codes

**Persistence & knowledge**
- `memory` — IndexedDB key-value memory
- `knowledge-graph` — graphology-backed entity/relation graph with BFS, Dijkstra, Louvain communities
- `gallery` — save/recall rendered UI panels

**Research**
- `github` — GraphQL v4 against the GitHub API (repos, issues, PRs, search, everything)
- `time-tools` — word count, timestamps, search-replace, UI config

**System**
- `scheduler` — recurring + one-time tasks, persisted to IDB, rehydrates on boot
- `notification` — native Notification API
- `geolocation` — browser geolocation
- `telegram` — Telegram bot messaging
- `clipboard` — read/write clipboard
- `panel` — open/close UI panels declaratively
- `core` — `render_ui`, `javascript_eval`, `storage_*`, `fetch_url`

### 🪝 React hooks

- **`useAgent`** — the core: one Agent instance, IDB persistence per thread, streaming, cancellation, auto self-heal on context overflow, message mgmt, event-bus integration, metrics, regenerate
- **`useAgents`** — multi-agent registry for spawning sibling agents in the same tab
- `useMesh` — reactive peer list + ring context via BroadcastChannel
- `useEventBus` — subscribe to the unified event stream (task/scheduler/telegram/webhook/tool/ambient/mesh/error)
- `useThreads` — multi-conversation persistence with rename/pin/delete
- `useUserActivity` — typing/mouse/scroll/idle/battery/network/orientation/visibility tracking for dynamic context
- `useBookmarks` — persistent message bookmarks
- `useAmbient` — autonomous idle-time agent loop with `[AMBIENT_DONE]` signal
- `useTaskListener` — listen for scheduled task fires
- `useVoiceCommand` — continuous SpeechRecognition with trigger phrases
- `useKeyboardShortcuts` — declarative keybind registration
- `useTheme` — dark/light with `data-theme` sync
- `useSettings` — localStorage + cross-tab sync
- `useWebRTC` — peer-to-peer data channels with heartbeat + backoff reconnect

### 📚 Helper libraries (`/lib`)

- `buildSystemPrompt` — dynamic, context-rich system prompts with tool hints
- `toDisplayMessages` / `serializeMessages` — SDK ↔ UI message conversion
- `estimateTotalTokens` / `shouldSummarize` — rolling-summary heuristics
- `mesh` / `MeshImpl` — cross-tab coordination singleton
- `turn-log` — 200-turn continuous memory ring buffer
- `event-bus` — unified agent activity stream with sessionStorage persistence
- `cost-estimator` — USD + context window per provider+model
- `webrtc-mesh` — RTCPeerConnection-based peer mesh with signaling via BC
- `agent-registry` — in-memory multi-agent registry

### 🔌 Model providers (`/providers`)

Lazy-loaded factory for: Anthropic, OpenAI, Google Gemini, AWS Bedrock, Vercel AI SDK (with 20+ providers).

## Usage

### Minimum viable chat UI

```tsx
import { useAgent } from '@cagataycali/strands-tools/hooks'
import { GITHUB_TOOLS, MEMORY_TOOLS } from '@cagataycali/strands-tools/tools'

function Chat({ settings }) {
  const agent = useAgent(settings, 'my-thread', [
    ...GITHUB_TOOLS,
    ...MEMORY_TOOLS,
  ])

  return (
    <div>
      {agent.getMessages().map((m, i) => <div key={i}>{m.role}: {m.content}</div>)}
      <input onKeyDown={e => {
        if (e.key === 'Enter') {
          agent.send(e.currentTarget.value)
          e.currentTarget.value = ''
        }
      }} />
    </div>
  )
}
```

### Everything at once

```tsx
import { useAgent, useAgents, useMesh, useThreads } from '@cagataycali/strands-tools/hooks'
import { buildTools, TOOL_GROUPS } from '@cagataycali/strands-tools/tools'

const tools = buildTools(settings) // respects settings.enableTools etc.
const agent = useAgent(settings, threads.storageKey, tools)
const siblings = useAgents(settings)
const { peers, ring } = useMesh()
```

### Granular imports (tree-shaking friendly)

```ts
import { githubSearchReposTool, githubGetRepoTool } from '@cagataycali/strands-tools/tools/github'
import { useAgent } from '@cagataycali/strands-tools/hooks/useAgent'
import { buildSystemPrompt } from '@cagataycali/strands-tools/lib/system-prompt'
```

## Philosophy

- **Two paths, unified.** Some tools run browser-native (lodash, date-fns, zod). Some need Node (sharp, sqlite3, express). The `npm` tool auto-routes.
- **Agent self-management is first-class.** `manage_messages`, `manage_tools`, and `self-modify` let the agent prune its own context, load capabilities at runtime, and evolve its system prompt.
- **Multi-agent by design.** `useAgents` + `mesh` + `multi-agent` tools = one tab can host many coordinating agents, each with its own history.
- **Tree-shake aggressively.** Every tool and hook is a leaf import. Use only what you need.
- **Browser-native.** No backend required. Runs on GitHub Pages, Vercel, anywhere that serves static files.

## Architecture

`useAgent` owns the SDK's `Agent` instance. The SDK's `agent.messages` IS the conversation state — no duplicate React state to keep in sync. `agent.stream()` handles everything: user msg append, model call, tool execution, assistant msg append, cancellation via `AbortSignal`.

Per-thread persistence to IndexedDB (`careless-thread-{id}`). Auto-heals context overflow by dropping older half (preserving `toolUse ↔ toolResult` pairs) and retrying once. Proactive warn when >80% of context window via `shouldSummarize`.

## Compatibility

- **Modern browsers only** (Chrome/Edge 113+, Safari 18+, Firefox with `dom.webgpu.enabled`)
- **React 18+** for hooks
- **Strands Agents SDK 1.x**
- **Zod 4.x**

## Status

🚧 **v0.1.0 scaffold** — extracted from the [careless](https://careless.my) codebase. Stable API but will churn as the external surface solidifies. Pin exact versions until 1.0.

## License

MIT © Çağatay Çalı
