BREAKING CHANGE(api): Migrate public API to ai-sdk v6 and refactor core agent architecture: replace class-based DualAgent/Driver/Guardian with a single runAgent function; introduce ts_tools factories for tools, a compactMessages compaction subpath, and truncateOutput utility; simplify ToolRegistry to return ToolSet and remove legacy BaseToolWrapper/tool classes; update package exports and dependencies and bump major version.
This commit is contained in:
124
readme.hints.md
124
readme.hints.md
@@ -1,97 +1,51 @@
|
||||
# Project Readme Hints
|
||||
|
||||
## Overview
|
||||
`@push.rocks/smartagent` is a dual-agent agentic framework built on top of `@push.rocks/smartai`. It implements a Driver/Guardian architecture where the Driver proposes tool calls and the Guardian evaluates them against security policies.
|
||||
`@push.rocks/smartagent` v2.0.0 is an agentic loop built on Vercel AI SDK v6 via `@push.rocks/smartai`. It wraps `streamText` with `stopWhen: stepCountIs(n)` for parallel multi-step tool execution.
|
||||
|
||||
## Architecture
|
||||
- **DualAgentOrchestrator**: Main entry point, coordinates Driver and Guardian agents
|
||||
- **DriverAgent**: Reasons about tasks, plans steps, proposes tool calls (supports both XML and native tool calling)
|
||||
- **GuardianAgent**: Evaluates tool calls against configured policies
|
||||
- **ToolRegistry**: Manages tool lifecycle, visibility, and discovery
|
||||
- **BaseToolWrapper**: Base class for creating custom tools
|
||||
- **plugins.ts**: Imports and re-exports smartai and other dependencies
|
||||
## Architecture (v2)
|
||||
- **`runAgent()`**: Pure async function — the core agentic loop. No class state.
|
||||
- **`ToolRegistry`**: Lightweight helper for collecting tools into a `ToolSet`.
|
||||
- **`truncateOutput()`**: Utility to prevent tool output from bloating context.
|
||||
- **`compactMessages()`**: Context overflow handler (separate subpath export).
|
||||
|
||||
## Standard Tools (via registerStandardTools)
|
||||
1. **FilesystemTool** - File operations with scoping and exclusion patterns
|
||||
2. **HttpTool** - HTTP requests
|
||||
3. **ShellTool** - Secure shell commands (no injection possible)
|
||||
4. **BrowserTool** - Web page interaction via Puppeteer
|
||||
5. **DenoTool** - Sandboxed TypeScript/JavaScript execution
|
||||
|
||||
## Additional Tools (must register manually)
|
||||
6. **JsonValidatorTool** - JSON validation and formatting (NOT in registerStandardTools)
|
||||
7. **ToolSearchTool** - AI-facing interface for tool discovery and activation
|
||||
8. **ExpertTool** - Wraps a DualAgentOrchestrator as a specialized expert tool
|
||||
|
||||
## Tool Visibility System
|
||||
Tools can be registered with visibility modes:
|
||||
- **initial**: Always visible to Driver, included in system prompt (default)
|
||||
- **on-demand**: Only discoverable via search, must be activated before use
|
||||
|
||||
```typescript
|
||||
// Register with visibility options
|
||||
orchestrator.registerTool(myTool, {
|
||||
visibility: 'on-demand',
|
||||
tags: ['database', 'sql'],
|
||||
category: 'data'
|
||||
});
|
||||
## Source Layout
|
||||
```
|
||||
ts/ → core: runAgent, ToolRegistry, truncateOutput, interfaces
|
||||
ts_tools/ → built-in tool factories (filesystem, shell, http, json)
|
||||
ts_compaction/ → compactMessages helper for onContextOverflow
|
||||
```
|
||||
|
||||
## Expert/SubAgent System
|
||||
Experts are specialized agents wrapped as tools, enabling hierarchical agent architectures:
|
||||
|
||||
```typescript
|
||||
orchestrator.registerExpert({
|
||||
name: 'code_reviewer',
|
||||
description: 'Reviews code for quality and best practices',
|
||||
systemMessage: 'You are a code review expert...',
|
||||
guardianPolicy: 'Allow read-only file access',
|
||||
tools: [new FilesystemTool()],
|
||||
visibility: 'on-demand',
|
||||
tags: ['code', 'review']
|
||||
});
|
||||
```
|
||||
|
||||
## Tool Search
|
||||
Enable tool discovery for the Driver:
|
||||
|
||||
```typescript
|
||||
orchestrator.enableToolSearch();
|
||||
// Driver can now use:
|
||||
// - tools.search({"query": "database"})
|
||||
// - tools.list({})
|
||||
// - tools.activate({"name": "database_expert"})
|
||||
// - tools.details({"name": "filesystem"})
|
||||
```
|
||||
|
||||
## Key Features
|
||||
- Token streaming support (`onToken` callback)
|
||||
- Vision support (pass images as base64)
|
||||
- Progress events (`onProgress` callback)
|
||||
- Scoped filesystem with exclusion patterns
|
||||
- Result truncation with configurable limits
|
||||
- History windowing to manage token usage
|
||||
- **Native tool calling mode** (`useNativeToolCalling: true`) for providers like Ollama
|
||||
- **Tool visibility system** (initial vs on-demand)
|
||||
- **Expert/SubAgent system** for hierarchical agents
|
||||
- **Tool search and discovery** via ToolSearchTool
|
||||
|
||||
## Native Tool Calling
|
||||
When `useNativeToolCalling` is enabled:
|
||||
- Uses provider's built-in tool calling API instead of XML parsing
|
||||
- Tool names become `toolName_actionName` (e.g., `json_validate`)
|
||||
- Streaming includes `[THINKING]` and `[OUTPUT]` markers
|
||||
- More efficient for models that support it
|
||||
## Built-in Tools (ts_tools/)
|
||||
Each exports a factory returning a flat `ToolSet` (Record<string, Tool>):
|
||||
1. **filesystemTool()** → `read_file`, `write_file`, `list_directory`, `delete_file`
|
||||
2. **shellTool()** → `run_command`
|
||||
3. **httpTool()** → `http_get`, `http_post`
|
||||
4. **jsonTool()** → `json_validate`, `json_transform`
|
||||
|
||||
## Key Dependencies
|
||||
- `@push.rocks/smartai`: Multi-provider AI interface
|
||||
- `@push.rocks/smartfs`: Filesystem operations
|
||||
- `@push.rocks/smartshell`: Shell command execution
|
||||
- `@push.rocks/smartbrowser`: Browser automation
|
||||
- `@push.rocks/smartdeno`: Deno code execution
|
||||
- `@push.rocks/smartrequest`: HTTP requests
|
||||
- `minimatch`: Glob pattern matching for exclusions
|
||||
- `@push.rocks/smartai` ^2.0.0 — provider registry, `getModel()`, re-exports `tool`, `jsonSchema`
|
||||
- `ai` ^6.0.0 — Vercel AI SDK v6 (`streamText`, `stepCountIs`, `ModelMessage`, `ToolSet`)
|
||||
- `zod` ^3.25.0 — tool input schema definitions
|
||||
- `@push.rocks/smartfs`, `smartshell`, `smartrequest` — tool implementations
|
||||
|
||||
## AI SDK v6 Key APIs
|
||||
- `streamText({ model, messages, tools, stopWhen: stepCountIs(20) })` — agentic loop
|
||||
- `tool({ description, inputSchema: z.object({...}), execute })` — define tools
|
||||
- `ModelMessage` — message type (replaces v4's `CoreMessage`)
|
||||
- `LanguageModelV3` — model type from `@ai-sdk/provider`
|
||||
- Result is `StreamTextResult` with PromiseLike properties (`await result.text`, etc.)
|
||||
|
||||
## Package Exports
|
||||
- `.` → core (runAgent, ToolRegistry, truncateOutput, re-exports)
|
||||
- `./tools` → built-in tool factories
|
||||
- `./compaction` → compactMessages
|
||||
|
||||
## Build
|
||||
- `pnpm build` → `tsbuild tsfolders --allowimplicitany`
|
||||
- Cross-folder imports via each folder's `plugins.ts` (tsbuild unpack resolves them)
|
||||
|
||||
## Test Structure
|
||||
- Tests use `@git.zone/tstest/tapbundle`
|
||||
- Tests must end with `export default tap.start();`
|
||||
- Tests must end with `export default tap.start()`
|
||||
- `pnpm test` → `tstest test/ --verbose`
|
||||
|
||||
Reference in New Issue
Block a user