toolpack-sdk 1.4.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 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, 90 built-in tools, a workflow engine, and a flexible mode system — all through a single API.
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
  [![npm version](https://img.shields.io/npm/v/toolpack-sdk.svg)](https://www.npmjs.com/package/toolpack-sdk)
6
6
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
@@ -9,7 +9,7 @@ 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
@@ -18,7 +18,7 @@ A unified TypeScript/Node.js SDK for building AI-powered applications with multi
18
18
  - **Mode System** — Built-in Agent and Chat modes, plus `createMode()` for custom modes with tool filtering
19
19
  - **HITL Confirmation** — Human-in-the-loop approval for high-risk operations with configurable bypass rules
20
20
  - **Custom Providers** — Bring your own provider by implementing the `ProviderAdapter` interface
21
- - **90 Built-in Tools** across 11 categories:
21
+ - **97 Built-in Tools** across 12 categories:
22
22
  - **MCP Tool Server Integration** — dynamically bridge external Model Context Protocol servers into Toolpack as first-class tools via `createMcpToolProject()` and `disconnectMcpToolProject()`.
23
23
 
24
24
  | Category | Tools | Description |
@@ -31,6 +31,7 @@ A unified TypeScript/Node.js SDK for building AI-powered applications with multi
31
31
  | **`http-tools`** | 5 | HTTP requests — GET, POST, PUT, DELETE, download |
32
32
  | **`web-tools`** | 9 | Web interaction — fetch, search (Tavily/Brave/DuckDuckGo), scrape, extract links, map, metadata, sitemap, feed, screenshot |
33
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 |
34
35
  | **`diff-tools`** | 3 | Patch operations — create, apply, and preview diffs |
35
36
  | **`cloud-tools`** | 3 | Deployments — deploy, status, list (via Netlify) |
36
37
  | **`k8s-tools`** | 11 | Kubernetes cluster inspection and management via kubectl |
@@ -60,7 +61,7 @@ const sdk = await Toolpack.init({
60
61
  anthropic: {}, // Reads ANTHROPIC_API_KEY from env
61
62
  },
62
63
  defaultProvider: 'openai',
63
- tools: true, // Load all 90 built-in tools
64
+ tools: true, // Load all 97 built-in tools
64
65
  defaultMode: 'agent', // Agent mode with workflow engine
65
66
  });
66
67
 
@@ -140,19 +141,20 @@ See `packages/toolpack-sdk/docs/examples/kubernetes-usage.ts` for a complete exa
140
141
  | **Anthropic** | Claude Sonnet 4, Claude 3.5 Haiku, Claude 3 Opus | No embeddings support |
141
142
  | **Google Gemini** | Gemini 2.0 Flash, Gemini 1.5 Pro, Gemini 1.5 Flash | Synthetic tool call IDs |
142
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 |
143
145
 
144
146
  ### Provider Comparison
145
147
 
146
- | Capability | OpenAI | Anthropic | Gemini | Ollama |
147
- |------------|--------|-----------|--------|--------|
148
- | Chat completions | ✅ | ✅ | ✅ | ✅ |
149
- | Streaming | ✅ | ✅ | ✅ | ✅ |
150
- | Tool/function calling | ✅ | ✅ | ✅ | ✅ |
151
- | Multi-round tool loop | ✅ | ✅ | ✅ | ✅ |
152
- | Embeddings | ✅ | ❌ | ✅ | ✅ |
153
- | Vision/images | ✅ | ✅ | ✅ | ✅ (model-dependent) |
154
- | Tool name sanitization | ✅ (auto) | ✅ (auto) | ✅ (auto) | ✅ (auto) |
155
- | 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) |
156
158
 
157
159
  #### Provider-Specific Notes
158
160
 
@@ -201,6 +203,7 @@ const sdk = await Toolpack.init({
201
203
  See `docs/MCP_INTEGRATION.md` and `docs/examples/mcp-integration-example.ts` for full instructions and best practices.
202
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`.
203
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`.
204
207
 
205
208
  ### Custom Providers
206
209
 
@@ -548,7 +551,7 @@ client.on('tool:failed', (event) => { /* ... */ });
548
551
 
549
552
  ## Custom Tools
550
553
 
551
- In addition to the 90 built-in tools, you can create and register your own custom tool projects using `createToolProject()`:
554
+ In addition to the 97 built-in tools, you can create and register your own custom tool projects using `createToolProject()`:
552
555
 
553
556
  ```typescript
554
557
  import { Toolpack, createToolProject } from 'toolpack-sdk';
@@ -646,6 +649,355 @@ const response = await toolpack.chat('How do I configure authentication?');
646
649
 
647
650
  See the [Knowledge package README](../toolpack-knowledge/README.md) for full documentation.
648
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
+
649
1001
  ## Multimodal Support
650
1002
 
651
1003
  The SDK supports multimodal inputs (text + images) across all vision-capable providers. Images can be provided in three formats:
@@ -704,6 +1056,7 @@ const response = await sdk.generate({
704
1056
  export OPENAI_API_KEY="sk-..."
705
1057
  export ANTHROPIC_API_KEY="sk-ant-..."
706
1058
  export GOOGLE_GENERATIVE_AI_KEY="AIza..."
1059
+ export OPENROUTER_API_KEY="sk-or-..."
707
1060
 
708
1061
  # SDK logging (override — prefer toolpack.config.json instead)
709
1062
  export TOOLPACK_SDK_LOG_FILE="./toolpack.log" # Log file path (also enables logging)
@@ -926,6 +1279,7 @@ interface CompletionRequest {
926
1279
  temperature?: number;
927
1280
  max_tokens?: number;
928
1281
  tools?: ToolCallRequest[];
1282
+ requestTools?: RequestToolDefinition[]; // Request-scoped tools
929
1283
  tool_choice?: 'auto' | 'none' | 'required';
930
1284
  }
931
1285
 
@@ -956,6 +1310,115 @@ interface ProviderModelInfo {
956
1310
  }
957
1311
  ```
958
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
+
959
1422
  ## Error Handling
960
1423
 
961
1424
  The SDK provides typed error classes for common failure scenarios:
@@ -1008,10 +1471,11 @@ toolpack-sdk/
1008
1471
  │ │ ├── openai/ # OpenAI adapter
1009
1472
  │ │ ├── anthropic/ # Anthropic adapter
1010
1473
  │ │ ├── gemini/ # Google Gemini adapter
1474
+ │ │ ├── openrouter/ # OpenRouter adapter (OpenAI-compatible, dynamic model discovery)
1011
1475
  │ │ └── ollama/ # Ollama adapter + provider (auto-discovery)
1012
1476
  │ ├── modes/ # Mode system (Agent, Chat, createMode)
1013
1477
  │ ├── workflows/ # Workflow engine (planner, step executor, progress)
1014
- │ ├── tools/ # 90 built-in tools + registry + router + BM25 search
1478
+ │ ├── tools/ # 97 built-in tools + registry + router + BM25 search
1015
1479
  │ │ ├── fs-tools/ # File system (18 tools)
1016
1480
  │ │ ├── coding-tools/ # Code analysis (12 tools)
1017
1481
  │ │ ├── git-tools/ # Git operations (9 tools)
@@ -1037,7 +1501,7 @@ toolpack-sdk/
1037
1501
 
1038
1502
  **Current Version:** 0.1.0
1039
1503
 
1040
- - ✓ **4 Built-in Providers** — OpenAI, Anthropic, Gemini, Ollama (+ custom provider API)
1504
+ - ✓ **5 Built-in Providers** — OpenAI, Anthropic, Gemini, Ollama, OpenRouter (+ custom provider API)
1041
1505
  - ✓ **90 Built-in Tools** — fs, exec, git, diff, web, coding, db, cloud, http, system, Kubernetes
1042
1506
  - ✓ **Workflow Engine** — AI-driven planning, step execution, retries, dynamic steps, progress events
1043
1507
  - ✓ **Mode System** — Agent, Coding, Chat, and custom modes via `createMode()` with `blockAllTools` support