toolpack-sdk 1.3.0 → 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +566 -18
- package/dist/index.cjs +324 -139
- package/dist/index.d.cts +1057 -186
- package/dist/index.d.ts +1057 -186
- package/dist/index.js +326 -141
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Toolpack SDK
|
|
2
2
|
|
|
3
|
-
A unified TypeScript/Node.js SDK for building AI-powered applications with multiple providers,
|
|
3
|
+
A unified TypeScript/Node.js SDK for building AI-powered applications with multiple providers, 97 built-in tools, a workflow engine, and a flexible mode system — all through a single API.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/toolpack-sdk)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
@@ -9,15 +9,16 @@ A unified TypeScript/Node.js SDK for building AI-powered applications with multi
|
|
|
9
9
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
|
-
- **Unified API** — Single interface for OpenAI, Anthropic, Google Gemini, Ollama, and custom providers
|
|
12
|
+
- **Unified API** — Single interface for OpenAI, Anthropic, Google Gemini, Ollama, OpenRouter, and custom providers
|
|
13
13
|
- **Streaming** — Real-time response streaming across all providers
|
|
14
14
|
- **Type-Safe** — Comprehensive TypeScript types throughout
|
|
15
15
|
- **Multimodal** — Text and image inputs (vision) across all providers
|
|
16
16
|
- **Embeddings** — Vector generation for RAG applications (OpenAI, Gemini, Ollama)
|
|
17
17
|
- **Workflow Engine** — AI-driven planning and step-by-step task execution with progress events
|
|
18
18
|
- **Mode System** — Built-in Agent and Chat modes, plus `createMode()` for custom modes with tool filtering
|
|
19
|
+
- **HITL Confirmation** — Human-in-the-loop approval for high-risk operations with configurable bypass rules
|
|
19
20
|
- **Custom Providers** — Bring your own provider by implementing the `ProviderAdapter` interface
|
|
20
|
-
- **
|
|
21
|
+
- **97 Built-in Tools** across 12 categories:
|
|
21
22
|
- **MCP Tool Server Integration** — dynamically bridge external Model Context Protocol servers into Toolpack as first-class tools via `createMcpToolProject()` and `disconnectMcpToolProject()`.
|
|
22
23
|
|
|
23
24
|
| Category | Tools | Description |
|
|
@@ -30,8 +31,10 @@ A unified TypeScript/Node.js SDK for building AI-powered applications with multi
|
|
|
30
31
|
| **`http-tools`** | 5 | HTTP requests — GET, POST, PUT, DELETE, download |
|
|
31
32
|
| **`web-tools`** | 9 | Web interaction — fetch, search (Tavily/Brave/DuckDuckGo), scrape, extract links, map, metadata, sitemap, feed, screenshot |
|
|
32
33
|
| **`system-tools`** | 5 | System info — env vars, cwd, disk usage, system info, set env |
|
|
34
|
+
| **`github-tools`** | 9 | GitHub operations — PR reviews, review threads, file diffs, issue comments, GraphQL, repo contents |
|
|
33
35
|
| **`diff-tools`** | 3 | Patch operations — create, apply, and preview diffs |
|
|
34
36
|
| **`cloud-tools`** | 3 | Deployments — deploy, status, list (via Netlify) |
|
|
37
|
+
| **`k8s-tools`** | 11 | Kubernetes cluster inspection and management via kubectl |
|
|
35
38
|
| **`mcp-tools`** | 2 | MCP integration — createMcpToolProject, disconnectMcpToolProject |
|
|
36
39
|
|
|
37
40
|
## Quick Start
|
|
@@ -58,7 +61,7 @@ const sdk = await Toolpack.init({
|
|
|
58
61
|
anthropic: {}, // Reads ANTHROPIC_API_KEY from env
|
|
59
62
|
},
|
|
60
63
|
defaultProvider: 'openai',
|
|
61
|
-
tools: true, // Load all
|
|
64
|
+
tools: true, // Load all 97 built-in tools
|
|
62
65
|
defaultMode: 'agent', // Agent mode with workflow engine
|
|
63
66
|
});
|
|
64
67
|
|
|
@@ -90,6 +93,44 @@ const sdk = await Toolpack.init({
|
|
|
90
93
|
});
|
|
91
94
|
```
|
|
92
95
|
|
|
96
|
+
## Kubernetes Tools
|
|
97
|
+
|
|
98
|
+
Toolpack SDK now includes a dedicated Kubernetes tool category that exposes `kubectl`-backed operations when `tools: true` is enabled. Use these tools to inspect cluster state, fetch pod logs, apply manifests, and wait for rollout status.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const sdk = await Toolpack.init({
|
|
102
|
+
provider: 'openai',
|
|
103
|
+
tools: true,
|
|
104
|
+
defaultMode: 'agent',
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const podsResponse = await sdk.generate({
|
|
108
|
+
model: 'gpt-4o',
|
|
109
|
+
messages: [
|
|
110
|
+
{
|
|
111
|
+
role: 'user',
|
|
112
|
+
content: 'List pods in the default namespace using Kubernetes tools.',
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
});
|
|
116
|
+
console.log(podsResponse.content);
|
|
117
|
+
|
|
118
|
+
const applyResponse = await sdk.generate({
|
|
119
|
+
model: 'gpt-4o',
|
|
120
|
+
messages: [
|
|
121
|
+
{
|
|
122
|
+
role: 'user',
|
|
123
|
+
content: 'Apply the manifest at ./deploy/my-app.yaml to the staging namespace using Kubernetes tools.',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
console.log(applyResponse.content);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> Requires `kubectl` installed and configured with a valid kubeconfig.
|
|
131
|
+
|
|
132
|
+
See `packages/toolpack-sdk/docs/examples/kubernetes-usage.ts` for a complete example.
|
|
133
|
+
|
|
93
134
|
## Providers
|
|
94
135
|
|
|
95
136
|
### Built-in Providers
|
|
@@ -100,19 +141,20 @@ const sdk = await Toolpack.init({
|
|
|
100
141
|
| **Anthropic** | Claude Sonnet 4, Claude 3.5 Haiku, Claude 3 Opus | No embeddings support |
|
|
101
142
|
| **Google Gemini** | Gemini 2.0 Flash, Gemini 1.5 Pro, Gemini 1.5 Flash | Synthetic tool call IDs |
|
|
102
143
|
| **Ollama** | Auto-discovered from locally pulled models | Capability detection via probing |
|
|
144
|
+
| **OpenRouter** | All models at openrouter.ai (auto-discovered) | Access to 300+ models via OpenAI-compatible API |
|
|
103
145
|
|
|
104
146
|
### Provider Comparison
|
|
105
147
|
|
|
106
|
-
| Capability | OpenAI | Anthropic | Gemini | Ollama |
|
|
107
|
-
|
|
108
|
-
| Chat completions | ✅ | ✅ | ✅ | ✅ |
|
|
109
|
-
| Streaming | ✅ | ✅ | ✅ | ✅ |
|
|
110
|
-
| Tool/function calling | ✅ | ✅ | ✅ | ✅ |
|
|
111
|
-
| Multi-round tool loop | ✅ | ✅ | ✅ | ✅ |
|
|
112
|
-
| Embeddings | ✅ | ❌ | ✅ | ✅ |
|
|
113
|
-
| Vision/images | ✅ | ✅ | ✅ | ✅ (model-dependent) |
|
|
114
|
-
| Tool name sanitization | ✅ (auto) | ✅ (auto) | ✅ (auto) | ✅ (auto) |
|
|
115
|
-
| Model discovery | Static list | Static list | Static list | Dynamic (`/api/tags` + `/api/show`) |
|
|
148
|
+
| Capability | OpenAI | Anthropic | Gemini | Ollama | OpenRouter |
|
|
149
|
+
|------------|--------|-----------|--------|--------|------------|
|
|
150
|
+
| Chat completions | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
151
|
+
| Streaming | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
152
|
+
| Tool/function calling | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
153
|
+
| Multi-round tool loop | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
154
|
+
| Embeddings | ✅ | ❌ | ✅ | ✅ | ❌ |
|
|
155
|
+
| Vision/images | ✅ | ✅ | ✅ | ✅ (model-dependent) | ✅ (model-dependent) |
|
|
156
|
+
| Tool name sanitization | ✅ (auto) | ✅ (auto) | ✅ (auto) | ✅ (auto) | ✅ (auto) |
|
|
157
|
+
| Model discovery | Static list | Static list | Static list | Dynamic (`/api/tags` + `/api/show`) | Dynamic (`/models` endpoint) |
|
|
116
158
|
|
|
117
159
|
#### Provider-Specific Notes
|
|
118
160
|
|
|
@@ -161,6 +203,7 @@ const sdk = await Toolpack.init({
|
|
|
161
203
|
See `docs/MCP_INTEGRATION.md` and `docs/examples/mcp-integration-example.ts` for full instructions and best practices.
|
|
162
204
|
- **Gemini**: Uses synthetic tool call IDs (`gemini_<timestamp>_<random>`) since the Gemini API doesn't return tool call IDs natively. Tool results are converted to `functionResponse` parts in chat history automatically. API key read from `GOOGLE_GENERATIVE_AI_KEY` or `TOOLPACK_GEMINI_KEY`.
|
|
163
205
|
- **Ollama**: Auto-discovers all locally pulled models when registered as `{ ollama: {} }`. Uses `/api/show` and tool probing to detect capabilities (tool calling, vision, embeddings) per model. Models without tool support are automatically stripped of tools and given a system instruction to prevent hallucinated tool usage. Uses synthetic tool call IDs (`ollama_<timestamp>_<random>`). Embeddings use the modern `/api/embed` batch endpoint. Legacy per-model registration (`{ 'ollama-llama3': {} }`) is also supported.
|
|
206
|
+
- **OpenRouter**: Routes requests to any of the 300+ models available on [openrouter.ai](https://openrouter.ai) via an OpenAI-compatible API. Models are discovered dynamically from the `/models` endpoint. Tool calling is fully supported; models that reject `tool_choice: 'none'` have tools stripped gracefully instead. No embeddings support. Optional `siteUrl` and `siteName` config for OpenRouter's attribution leaderboard. API key read from `OPENROUTER_API_KEY` or `TOOLPACK_OPENROUTER_KEY`.
|
|
164
207
|
|
|
165
208
|
### Custom Providers
|
|
166
209
|
|
|
@@ -508,7 +551,7 @@ client.on('tool:failed', (event) => { /* ... */ });
|
|
|
508
551
|
|
|
509
552
|
## Custom Tools
|
|
510
553
|
|
|
511
|
-
In addition to the
|
|
554
|
+
In addition to the 97 built-in tools, you can create and register your own custom tool projects using `createToolProject()`:
|
|
512
555
|
|
|
513
556
|
```typescript
|
|
514
557
|
import { Toolpack, createToolProject } from 'toolpack-sdk';
|
|
@@ -606,6 +649,355 @@ const response = await toolpack.chat('How do I configure authentication?');
|
|
|
606
649
|
|
|
607
650
|
See the [Knowledge package README](../toolpack-knowledge/README.md) for full documentation.
|
|
608
651
|
|
|
652
|
+
## AI Agents (@toolpack-sdk/agents)
|
|
653
|
+
|
|
654
|
+
Build production-ready AI agents with channels, workflows, and event-driven architecture using the companion `@toolpack-sdk/agents` package:
|
|
655
|
+
|
|
656
|
+
```bash
|
|
657
|
+
npm install @toolpack-sdk/agents
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### What are Agents?
|
|
661
|
+
|
|
662
|
+
Agents are autonomous AI systems that:
|
|
663
|
+
- **Listen** for events from channels (Slack, webhooks, schedules, etc.)
|
|
664
|
+
- **Process** messages using the Toolpack SDK
|
|
665
|
+
- **Execute** tasks with full tool access
|
|
666
|
+
- **Respond** back through the same or different channels
|
|
667
|
+
- **Remember** conversations using knowledge bases
|
|
668
|
+
|
|
669
|
+
### Quick Start
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
import { Toolpack } from 'toolpack-sdk';
|
|
673
|
+
import { BaseAgent, AgentRegistry, SlackChannel } from '@toolpack-sdk/agents';
|
|
674
|
+
|
|
675
|
+
// 1. Create a custom agent
|
|
676
|
+
class SupportAgent extends BaseAgent {
|
|
677
|
+
name = 'support-agent';
|
|
678
|
+
description = 'Customer support agent that answers questions';
|
|
679
|
+
mode = 'chat';
|
|
680
|
+
|
|
681
|
+
async invokeAgent(input) {
|
|
682
|
+
const result = await this.run(input.message);
|
|
683
|
+
await this.sendTo('slack-support', result.output);
|
|
684
|
+
return result;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// 2. Set up channels
|
|
689
|
+
const slackChannel = new SlackChannel({
|
|
690
|
+
name: 'slack-support',
|
|
691
|
+
token: process.env.SLACK_BOT_TOKEN,
|
|
692
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET,
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
// 3. Register agent and channels
|
|
696
|
+
const registry = new AgentRegistry([
|
|
697
|
+
{ agent: SupportAgent, channels: [slackChannel] },
|
|
698
|
+
]);
|
|
699
|
+
|
|
700
|
+
// 4. Initialize Toolpack with agents
|
|
701
|
+
const sdk = await Toolpack.init({
|
|
702
|
+
provider: 'openai',
|
|
703
|
+
tools: true,
|
|
704
|
+
agents: registry,
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
// Agents now listen and respond automatically!
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### Built-in Agents
|
|
711
|
+
|
|
712
|
+
The package includes 4 production-ready agents you can use directly or extend:
|
|
713
|
+
|
|
714
|
+
#### ResearchAgent
|
|
715
|
+
```typescript
|
|
716
|
+
import { ResearchAgent } from '@toolpack-sdk/agents';
|
|
717
|
+
|
|
718
|
+
const agent = new ResearchAgent(sdk);
|
|
719
|
+
const result = await agent.invokeAgent({
|
|
720
|
+
message: 'Summarize recent developments in edge AI',
|
|
721
|
+
});
|
|
722
|
+
```
|
|
723
|
+
- **Mode:** `agent`
|
|
724
|
+
- **Tools:** web.search, web.fetch, web.scrape
|
|
725
|
+
- **Use Cases:** Market research, competitive analysis, trend monitoring
|
|
726
|
+
|
|
727
|
+
#### CodingAgent
|
|
728
|
+
```typescript
|
|
729
|
+
import { CodingAgent } from '@toolpack-sdk/agents';
|
|
730
|
+
|
|
731
|
+
const agent = new CodingAgent(sdk);
|
|
732
|
+
const result = await agent.invokeAgent({
|
|
733
|
+
message: 'Refactor the auth module to use the new SDK pattern',
|
|
734
|
+
});
|
|
735
|
+
```
|
|
736
|
+
- **Mode:** `coding`
|
|
737
|
+
- **Tools:** fs.*, coding.*, git.*, exec.*
|
|
738
|
+
- **Use Cases:** Code generation, refactoring, debugging, test writing
|
|
739
|
+
|
|
740
|
+
#### DataAgent
|
|
741
|
+
```typescript
|
|
742
|
+
import { DataAgent } from '@toolpack-sdk/agents';
|
|
743
|
+
|
|
744
|
+
const agent = new DataAgent(sdk);
|
|
745
|
+
const result = await agent.invokeAgent({
|
|
746
|
+
message: 'Generate a weekly summary of signups by region',
|
|
747
|
+
});
|
|
748
|
+
```
|
|
749
|
+
- **Mode:** `agent`
|
|
750
|
+
- **Tools:** db.*, fs.*, http.*
|
|
751
|
+
- **Use Cases:** Database queries, reporting, data analysis, CSV generation
|
|
752
|
+
|
|
753
|
+
#### BrowserAgent
|
|
754
|
+
```typescript
|
|
755
|
+
import { BrowserAgent } from '@toolpack-sdk/agents';
|
|
756
|
+
|
|
757
|
+
const agent = new BrowserAgent(sdk);
|
|
758
|
+
const result = await agent.invokeAgent({
|
|
759
|
+
message: 'Extract all product prices from acme.com/products',
|
|
760
|
+
});
|
|
761
|
+
```
|
|
762
|
+
- **Mode:** `chat`
|
|
763
|
+
- **Tools:** web.fetch, web.screenshot, web.extract_links
|
|
764
|
+
- **Use Cases:** Web scraping, form filling, content extraction
|
|
765
|
+
|
|
766
|
+
### Channels
|
|
767
|
+
|
|
768
|
+
Channels connect agents to the outside world. The package includes 7 built-in channels:
|
|
769
|
+
|
|
770
|
+
#### SlackChannel (Two-way)
|
|
771
|
+
```typescript
|
|
772
|
+
import { SlackChannel } from '@toolpack-sdk/agents';
|
|
773
|
+
|
|
774
|
+
const slack = new SlackChannel({
|
|
775
|
+
name: 'slack-support',
|
|
776
|
+
token: process.env.SLACK_BOT_TOKEN,
|
|
777
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET,
|
|
778
|
+
});
|
|
779
|
+
```
|
|
780
|
+
- ✅ Receives messages from Slack
|
|
781
|
+
- ✅ Replies in threads
|
|
782
|
+
- ✅ Supports `ask()` for human input
|
|
783
|
+
|
|
784
|
+
#### TelegramChannel (Two-way)
|
|
785
|
+
```typescript
|
|
786
|
+
import { TelegramChannel } from '@toolpack-sdk/agents';
|
|
787
|
+
|
|
788
|
+
const telegram = new TelegramChannel({
|
|
789
|
+
name: 'telegram-bot',
|
|
790
|
+
token: process.env.TELEGRAM_BOT_TOKEN,
|
|
791
|
+
});
|
|
792
|
+
```
|
|
793
|
+
- ✅ Receives messages from Telegram
|
|
794
|
+
- ✅ Replies to users
|
|
795
|
+
- ✅ Supports `ask()` for human input
|
|
796
|
+
|
|
797
|
+
#### WebhookChannel (Two-way)
|
|
798
|
+
```typescript
|
|
799
|
+
import { WebhookChannel } from '@toolpack-sdk/agents';
|
|
800
|
+
|
|
801
|
+
const webhook = new WebhookChannel({
|
|
802
|
+
name: 'github-webhook',
|
|
803
|
+
path: '/webhook/github',
|
|
804
|
+
port: 3000,
|
|
805
|
+
secret: process.env.WEBHOOK_SECRET,
|
|
806
|
+
});
|
|
807
|
+
```
|
|
808
|
+
- ✅ Receives HTTP POST webhooks
|
|
809
|
+
- ✅ Signature verification
|
|
810
|
+
- ✅ Supports `ask()` for human input
|
|
811
|
+
|
|
812
|
+
#### ScheduledChannel (Trigger-only)
|
|
813
|
+
```typescript
|
|
814
|
+
import { ScheduledChannel } from '@toolpack-sdk/agents';
|
|
815
|
+
|
|
816
|
+
const scheduler = new ScheduledChannel({
|
|
817
|
+
name: 'daily-report',
|
|
818
|
+
cron: '0 9 * * 1-5', // 9am weekdays
|
|
819
|
+
notify: 'webhook:https://hooks.example.com/daily-report',
|
|
820
|
+
message: 'Generate the daily sales report',
|
|
821
|
+
});
|
|
822
|
+
// For Slack delivery, attach a named SlackChannel to the same agent and
|
|
823
|
+
// call `this.sendTo('<slackChannelName>', output)` from within `run()`.
|
|
824
|
+
```
|
|
825
|
+
- ⏰ Triggers agents on cron schedules
|
|
826
|
+
- ✅ Full cron expression support (ranges, steps, lists, combinations)
|
|
827
|
+
- ❌ No `ask()` support (no human recipient)
|
|
828
|
+
|
|
829
|
+
#### DiscordChannel (Two-way)
|
|
830
|
+
```typescript
|
|
831
|
+
import { DiscordChannel } from '@toolpack-sdk/agents';
|
|
832
|
+
|
|
833
|
+
const discord = new DiscordChannel({
|
|
834
|
+
name: 'discord-bot',
|
|
835
|
+
token: process.env.DISCORD_BOT_TOKEN,
|
|
836
|
+
guildId: 'your-guild-id',
|
|
837
|
+
channelId: 'your-channel-id',
|
|
838
|
+
});
|
|
839
|
+
```
|
|
840
|
+
- ✅ Receives messages from Discord
|
|
841
|
+
- ✅ Replies in threads
|
|
842
|
+
- ✅ Supports `ask()` for human input
|
|
843
|
+
|
|
844
|
+
#### EmailChannel (Outbound-only)
|
|
845
|
+
```typescript
|
|
846
|
+
import { EmailChannel } from '@toolpack-sdk/agents';
|
|
847
|
+
|
|
848
|
+
const email = new EmailChannel({
|
|
849
|
+
name: 'email-alerts',
|
|
850
|
+
from: 'bot@acme.com',
|
|
851
|
+
to: 'team@acme.com',
|
|
852
|
+
smtp: {
|
|
853
|
+
host: 'smtp.gmail.com',
|
|
854
|
+
port: 587,
|
|
855
|
+
auth: { user: 'bot@acme.com', pass: process.env.SMTP_PASSWORD },
|
|
856
|
+
},
|
|
857
|
+
});
|
|
858
|
+
```
|
|
859
|
+
- 📧 Sends emails via SMTP
|
|
860
|
+
- ❌ No `ask()` support (outbound-only)
|
|
861
|
+
|
|
862
|
+
#### SMSChannel (Configurable)
|
|
863
|
+
```typescript
|
|
864
|
+
import { SMSChannel } from '@toolpack-sdk/agents';
|
|
865
|
+
|
|
866
|
+
// Two-way with webhook
|
|
867
|
+
const sms = new SMSChannel({
|
|
868
|
+
name: 'sms-alerts',
|
|
869
|
+
accountSid: process.env.TWILIO_ACCOUNT_SID,
|
|
870
|
+
authToken: process.env.TWILIO_AUTH_TOKEN,
|
|
871
|
+
from: '+1234567890',
|
|
872
|
+
webhookPath: '/sms/webhook', // Enables two-way
|
|
873
|
+
port: 3000,
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
// Outbound-only
|
|
877
|
+
const smsOutbound = new SMSChannel({
|
|
878
|
+
name: 'sms-notifications',
|
|
879
|
+
accountSid: process.env.TWILIO_ACCOUNT_SID,
|
|
880
|
+
authToken: process.env.TWILIO_AUTH_TOKEN,
|
|
881
|
+
from: '+1234567890',
|
|
882
|
+
to: '+0987654321', // Fixed recipient
|
|
883
|
+
});
|
|
884
|
+
```
|
|
885
|
+
- 📱 Twilio SMS integration
|
|
886
|
+
- ✅ Two-way when `webhookPath` is set
|
|
887
|
+
- ❌ Outbound-only without webhook
|
|
888
|
+
|
|
889
|
+
### Agent Lifecycle & Events
|
|
890
|
+
|
|
891
|
+
Agents emit events at each stage of execution:
|
|
892
|
+
|
|
893
|
+
```typescript
|
|
894
|
+
const agent = new MyAgent(sdk);
|
|
895
|
+
|
|
896
|
+
agent.on('agent:start', (input) => {
|
|
897
|
+
console.log('Agent started:', input.message);
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
agent.on('agent:complete', (result) => {
|
|
901
|
+
console.log('Agent completed:', result.output);
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
agent.on('agent:error', (error) => {
|
|
905
|
+
console.error('Agent error:', error);
|
|
906
|
+
});
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
### Knowledge Integration
|
|
910
|
+
|
|
911
|
+
Agents can use knowledge bases for conversation memory and RAG:
|
|
912
|
+
|
|
913
|
+
```typescript
|
|
914
|
+
import { Knowledge, MemoryProvider, OllamaEmbedder } from '@toolpack-sdk/knowledge';
|
|
915
|
+
import { BaseAgent } from '@toolpack-sdk/agents';
|
|
916
|
+
|
|
917
|
+
class SmartAgent extends BaseAgent {
|
|
918
|
+
name = 'smart-agent';
|
|
919
|
+
description = 'Agent with memory';
|
|
920
|
+
mode = 'chat';
|
|
921
|
+
|
|
922
|
+
constructor(toolpack) {
|
|
923
|
+
super(toolpack);
|
|
924
|
+
// Set up knowledge base
|
|
925
|
+
this.knowledge = await Knowledge.create({
|
|
926
|
+
provider: new MemoryProvider(),
|
|
927
|
+
embedder: new OllamaEmbedder({ model: 'nomic-embed-text' }),
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
async invokeAgent(input) {
|
|
932
|
+
// Conversation history is automatically loaded from knowledge
|
|
933
|
+
const result = await this.run(input.message);
|
|
934
|
+
return result;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
### Multi-Channel Routing
|
|
940
|
+
|
|
941
|
+
Agents can send output to different channels:
|
|
942
|
+
|
|
943
|
+
```typescript
|
|
944
|
+
class MultiChannelAgent extends BaseAgent {
|
|
945
|
+
name = 'multi-agent';
|
|
946
|
+
description = 'Routes to multiple channels';
|
|
947
|
+
mode = 'agent';
|
|
948
|
+
|
|
949
|
+
async invokeAgent(input) {
|
|
950
|
+
const result = await this.run(input.message);
|
|
951
|
+
|
|
952
|
+
// Send to multiple channels
|
|
953
|
+
await this.sendTo('slack:#general', result.output);
|
|
954
|
+
await this.sendTo('email-team', result.output);
|
|
955
|
+
await this.sendTo('sms-alerts', 'Task completed!');
|
|
956
|
+
|
|
957
|
+
return result;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
### Extending Built-in Agents
|
|
963
|
+
|
|
964
|
+
```typescript
|
|
965
|
+
import { ResearchAgent } from '@toolpack-sdk/agents';
|
|
966
|
+
|
|
967
|
+
class FintechResearchAgent extends ResearchAgent {
|
|
968
|
+
systemPrompt = `You are a research agent focused on fintech.
|
|
969
|
+
Always cite sources and flag regulatory implications.`;
|
|
970
|
+
provider = 'anthropic';
|
|
971
|
+
model = 'claude-sonnet-4-20250514';
|
|
972
|
+
|
|
973
|
+
async onComplete(result) {
|
|
974
|
+
// Store research in knowledge base
|
|
975
|
+
if (this.knowledge) {
|
|
976
|
+
await this.knowledge.add(result.output, {
|
|
977
|
+
category: 'research',
|
|
978
|
+
topic: 'fintech',
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// Send to Slack
|
|
983
|
+
await this.sendTo('slack-research', result.output);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
### Features
|
|
989
|
+
|
|
990
|
+
- ✅ **7 Built-in Channels** — Slack, Telegram, Discord, Email, SMS, Webhook, Scheduled
|
|
991
|
+
- ✅ **4 Built-in Agents** — Research, Coding, Data, Browser
|
|
992
|
+
- ✅ **Event-Driven** — Full lifecycle events for monitoring
|
|
993
|
+
- ✅ **Knowledge Integration** — Conversation memory and RAG
|
|
994
|
+
- ✅ **Multi-Channel Routing** — Send to any registered channel
|
|
995
|
+
- ✅ **Human-in-the-Loop** — `ask()` support for two-way channels
|
|
996
|
+
- ✅ **Type-Safe** — Full TypeScript support
|
|
997
|
+
- ✅ **199 Tests Passing** — Production-ready
|
|
998
|
+
|
|
999
|
+
See the [Agents package README](../toolpack-agents/README.md) for full documentation.
|
|
1000
|
+
|
|
609
1001
|
## Multimodal Support
|
|
610
1002
|
|
|
611
1003
|
The SDK supports multimodal inputs (text + images) across all vision-capable providers. Images can be provided in three formats:
|
|
@@ -664,6 +1056,7 @@ const response = await sdk.generate({
|
|
|
664
1056
|
export OPENAI_API_KEY="sk-..."
|
|
665
1057
|
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
666
1058
|
export GOOGLE_GENERATIVE_AI_KEY="AIza..."
|
|
1059
|
+
export OPENROUTER_API_KEY="sk-or-..."
|
|
667
1060
|
|
|
668
1061
|
# SDK logging (override — prefer toolpack.config.json instead)
|
|
669
1062
|
export TOOLPACK_SDK_LOG_FILE="./toolpack.log" # Log file path (also enables logging)
|
|
@@ -766,6 +1159,49 @@ Create a `toolpack.config.json` in your project root:
|
|
|
766
1159
|
| `enabledTools` | string[] | `[]` | Whitelist specific tools (empty = all) |
|
|
767
1160
|
| `enabledToolCategories` | string[] | `[]` | Whitelist categories (empty = all) |
|
|
768
1161
|
|
|
1162
|
+
### HITL (Human-in-the-Loop) Configuration
|
|
1163
|
+
|
|
1164
|
+
Configure user confirmation for high-risk tool operations:
|
|
1165
|
+
|
|
1166
|
+
```json
|
|
1167
|
+
{
|
|
1168
|
+
"hitl": {
|
|
1169
|
+
"enabled": true,
|
|
1170
|
+
"confirmationMode": "all",
|
|
1171
|
+
"bypass": {
|
|
1172
|
+
"tools": ["fs.write_file"],
|
|
1173
|
+
"categories": ["filesystem"],
|
|
1174
|
+
"levels": ["medium"]
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
| Option | Type | Default | Description |
|
|
1181
|
+
|--------|------|---------|-------------|
|
|
1182
|
+
| `enabled` | boolean | `true` | Master switch for HITL confirmation |
|
|
1183
|
+
| `confirmationMode` | string | `"all"` | `"off"`, `"high-only"`, or `"all"` |
|
|
1184
|
+
| `bypass.tools` | string[] | `[]` | Tool names to bypass (e.g., `["fs.write_file"]`) |
|
|
1185
|
+
| `bypass.categories` | string[] | `[]` | Categories to bypass (e.g., `["filesystem"]`) |
|
|
1186
|
+
| `bypass.levels` | string[] | `[]` | Risk levels to bypass (`["high"]` or `["medium"]`) |
|
|
1187
|
+
|
|
1188
|
+
**Programmatic API:**
|
|
1189
|
+
|
|
1190
|
+
```typescript
|
|
1191
|
+
import { addBypassRule, removeBypassRule } from 'toolpack-sdk';
|
|
1192
|
+
|
|
1193
|
+
// Add bypass rule
|
|
1194
|
+
await addBypassRule({ type: 'tool', value: 'fs.delete_file' });
|
|
1195
|
+
|
|
1196
|
+
// Remove bypass rule
|
|
1197
|
+
await removeBypassRule({ type: 'tool', value: 'fs.delete_file' });
|
|
1198
|
+
|
|
1199
|
+
// Reload config to apply changes
|
|
1200
|
+
toolpack.reloadConfig();
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
See the [HITL documentation](https://toolpacksdk.com/guides/hitl-confirmation) for detailed configuration options and best practices.
|
|
1204
|
+
|
|
769
1205
|
#### Web Search Providers
|
|
770
1206
|
|
|
771
1207
|
The `web.search` tool supports multiple search backends with automatic fallback:
|
|
@@ -843,6 +1279,7 @@ interface CompletionRequest {
|
|
|
843
1279
|
temperature?: number;
|
|
844
1280
|
max_tokens?: number;
|
|
845
1281
|
tools?: ToolCallRequest[];
|
|
1282
|
+
requestTools?: RequestToolDefinition[]; // Request-scoped tools
|
|
846
1283
|
tool_choice?: 'auto' | 'none' | 'required';
|
|
847
1284
|
}
|
|
848
1285
|
|
|
@@ -873,6 +1310,115 @@ interface ProviderModelInfo {
|
|
|
873
1310
|
}
|
|
874
1311
|
```
|
|
875
1312
|
|
|
1313
|
+
### Request-Scoped Tools
|
|
1314
|
+
|
|
1315
|
+
Request-scoped tools are dynamic tools attached to a single completion request. Unlike globally registered tools in the ToolRegistry, they:
|
|
1316
|
+
|
|
1317
|
+
- **Don't pollute the shared registry** — Each request can have its own tools
|
|
1318
|
+
- **Can close over request-specific state** — e.g., `conversationId`, user context
|
|
1319
|
+
- **Are safe for multi-agent/multi-request usage** — No cross-request contamination
|
|
1320
|
+
- **Execute through the same SDK orchestration** — Events, logging, HITL all work
|
|
1321
|
+
|
|
1322
|
+
#### Built-in Request-Scoped Tools
|
|
1323
|
+
|
|
1324
|
+
**Knowledge Tools** (when `knowledge` is configured):
|
|
1325
|
+
- `knowledge_search` — Search the knowledge base for relevant information
|
|
1326
|
+
- `knowledge_add` — Add new content to the knowledge base at runtime
|
|
1327
|
+
|
|
1328
|
+
**Conversation Tools** (when using `ConversationHistory`):
|
|
1329
|
+
- `conversation_search` — Search conversation history for past messages
|
|
1330
|
+
|
|
1331
|
+
#### Creating Custom Request Tools
|
|
1332
|
+
|
|
1333
|
+
```typescript
|
|
1334
|
+
import { RequestToolDefinition, ConversationHistory } from 'toolpack-sdk';
|
|
1335
|
+
|
|
1336
|
+
// Example: Session-specific calculator
|
|
1337
|
+
const createCalculatorTool = (sessionId: string): RequestToolDefinition => ({
|
|
1338
|
+
name: 'calculate',
|
|
1339
|
+
displayName: 'Calculator',
|
|
1340
|
+
description: 'Perform mathematical calculations',
|
|
1341
|
+
category: 'math',
|
|
1342
|
+
parameters: {
|
|
1343
|
+
type: 'object',
|
|
1344
|
+
properties: {
|
|
1345
|
+
expression: { type: 'string', description: 'Math expression to evaluate' },
|
|
1346
|
+
},
|
|
1347
|
+
required: ['expression'],
|
|
1348
|
+
},
|
|
1349
|
+
execute: async (args) => {
|
|
1350
|
+
// Can safely close over sessionId
|
|
1351
|
+
console.log(`Session ${sessionId}: calculating ${args.expression}`);
|
|
1352
|
+
|
|
1353
|
+
// Simple eval (use a proper math library in production)
|
|
1354
|
+
const result = eval(args.expression);
|
|
1355
|
+
return { result, sessionId };
|
|
1356
|
+
},
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
// Use in a request
|
|
1360
|
+
const result = await sdk.generate({
|
|
1361
|
+
messages: [{ role: 'user', content: 'What is 15 * 23?' }],
|
|
1362
|
+
model: 'gpt-4',
|
|
1363
|
+
requestTools: [createCalculatorTool('user-123')],
|
|
1364
|
+
});
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
#### Using ConversationHistory with Request Tools
|
|
1368
|
+
|
|
1369
|
+
```typescript
|
|
1370
|
+
import { ConversationHistory } from 'toolpack-sdk';
|
|
1371
|
+
|
|
1372
|
+
const history = new ConversationHistory('./chat.db');
|
|
1373
|
+
|
|
1374
|
+
// Add some messages
|
|
1375
|
+
await history.addUserMessage('conv-1', 'What is the API rate limit?');
|
|
1376
|
+
await history.addAssistantMessage('conv-1', 'The rate limit is 100 requests per minute.');
|
|
1377
|
+
|
|
1378
|
+
// Use conversation search in a request
|
|
1379
|
+
const result = await sdk.generate({
|
|
1380
|
+
messages: [
|
|
1381
|
+
{ role: 'user', content: 'What did we discuss about rate limits?' }
|
|
1382
|
+
],
|
|
1383
|
+
model: 'gpt-4',
|
|
1384
|
+
requestTools: [
|
|
1385
|
+
history.toTool('conv-1'), // Scoped to conversation 'conv-1'
|
|
1386
|
+
],
|
|
1387
|
+
});
|
|
1388
|
+
|
|
1389
|
+
// AI can now call conversation_search to find the earlier discussion
|
|
1390
|
+
```
|
|
1391
|
+
|
|
1392
|
+
#### Request Tools vs Registry Tools
|
|
1393
|
+
|
|
1394
|
+
| Feature | Request Tools | Registry Tools |
|
|
1395
|
+
|---------|---------------|----------------|
|
|
1396
|
+
| **Scope** | Single request | All requests |
|
|
1397
|
+
| **State** | Can close over request state | Stateless |
|
|
1398
|
+
| **Registration** | Per-request via `requestTools` | Global via `ToolRegistry` |
|
|
1399
|
+
| **Use Case** | Dynamic, stateful tools | Reusable, static tools |
|
|
1400
|
+
| **Priority** | Higher (checked first) | Lower |
|
|
1401
|
+
| **Examples** | `conversation_search`, `knowledge_add` | `fs.read_file`, `web.search` |
|
|
1402
|
+
|
|
1403
|
+
#### Automatic Guidance Injection
|
|
1404
|
+
|
|
1405
|
+
When request-scoped tools are present, the SDK automatically injects usage guidance into the system prompt:
|
|
1406
|
+
|
|
1407
|
+
```
|
|
1408
|
+
Knowledge Base:
|
|
1409
|
+
- Use `knowledge_search` when you need factual or domain-specific information.
|
|
1410
|
+
- Use `knowledge_add` when you learn durable information that should be saved.
|
|
1411
|
+
|
|
1412
|
+
Conversation History:
|
|
1413
|
+
- Only recent messages may be present in context.
|
|
1414
|
+
- Use `conversation_search` to find details from earlier in this conversation.
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
This guidance is:
|
|
1418
|
+
- **Per-request** — Only injected when tools are actually present
|
|
1419
|
+
- **Derived from effective tool set** — Reflects the actual tools available
|
|
1420
|
+
- **Idempotent** — Won't duplicate if already present
|
|
1421
|
+
|
|
876
1422
|
## Error Handling
|
|
877
1423
|
|
|
878
1424
|
The SDK provides typed error classes for common failure scenarios:
|
|
@@ -925,10 +1471,11 @@ toolpack-sdk/
|
|
|
925
1471
|
│ │ ├── openai/ # OpenAI adapter
|
|
926
1472
|
│ │ ├── anthropic/ # Anthropic adapter
|
|
927
1473
|
│ │ ├── gemini/ # Google Gemini adapter
|
|
1474
|
+
│ │ ├── openrouter/ # OpenRouter adapter (OpenAI-compatible, dynamic model discovery)
|
|
928
1475
|
│ │ └── ollama/ # Ollama adapter + provider (auto-discovery)
|
|
929
1476
|
│ ├── modes/ # Mode system (Agent, Chat, createMode)
|
|
930
1477
|
│ ├── workflows/ # Workflow engine (planner, step executor, progress)
|
|
931
|
-
│ ├── tools/ #
|
|
1478
|
+
│ ├── tools/ # 97 built-in tools + registry + router + BM25 search
|
|
932
1479
|
│ │ ├── fs-tools/ # File system (18 tools)
|
|
933
1480
|
│ │ ├── coding-tools/ # Code analysis (12 tools)
|
|
934
1481
|
│ │ ├── git-tools/ # Git operations (9 tools)
|
|
@@ -939,6 +1486,7 @@ toolpack-sdk/
|
|
|
939
1486
|
│ │ ├── system-tools/ # System info (5 tools)
|
|
940
1487
|
│ │ ├── diff-tools/ # Patch operations (3 tools)
|
|
941
1488
|
│ │ ├── cloud-tools/ # Deployments (3 tools)
|
|
1489
|
+
│ │ ├── k8s-tools/ # Kubernetes management (11 tools)
|
|
942
1490
|
│ │ ├── registry.ts # Tool registry and loading
|
|
943
1491
|
│ │ ├── router.ts # Tool routing and filtering
|
|
944
1492
|
│ │ └── search/ # BM25 tool discovery engine (internal)
|
|
@@ -953,8 +1501,8 @@ toolpack-sdk/
|
|
|
953
1501
|
|
|
954
1502
|
**Current Version:** 0.1.0
|
|
955
1503
|
|
|
956
|
-
- ✓ **
|
|
957
|
-
- ✓ **
|
|
1504
|
+
- ✓ **5 Built-in Providers** — OpenAI, Anthropic, Gemini, Ollama, OpenRouter (+ custom provider API)
|
|
1505
|
+
- ✓ **90 Built-in Tools** — fs, exec, git, diff, web, coding, db, cloud, http, system, Kubernetes
|
|
958
1506
|
- ✓ **Workflow Engine** — AI-driven planning, step execution, retries, dynamic steps, progress events
|
|
959
1507
|
- ✓ **Mode System** — Agent, Coding, Chat, and custom modes via `createMode()` with `blockAllTools` support
|
|
960
1508
|
- ✓ **Tool Search** — BM25-based on-demand tool discovery for large tool libraries
|