toolpack-sdk 1.4.0 → 2.0.0
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 +587 -103
- package/dist/index.cjs +442 -171
- package/dist/index.d.cts +930 -123
- package/dist/index.d.ts +930 -123
- package/dist/index.js +444 -173
- package/package.json +9 -3
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, 100+ 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,31 +9,34 @@ 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
|
-
- **Workflow Engine** — AI-driven planning
|
|
17
|
+
- **Workflow Engine** — AI-driven planning with plan-direct execution and parallel tool orchestration
|
|
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
|
-
- **
|
|
21
|
+
- **101 Built-in Tools** across 14 categories (including 4 skill-tools and 2 mcp-tools):
|
|
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 |
|
|
25
25
|
|----------|-------|-------------|
|
|
26
26
|
| **`fs-tools`** | 18 | File system operations — read, write, search, tree, glob, batch read/write, etc. |
|
|
27
27
|
| **`coding-tools`** | 12 | Code analysis — AST parsing, go to definition, find references, rename symbols, extract function |
|
|
28
|
-
| **`git-tools`** |
|
|
28
|
+
| **`git-tools`** | 10 | Version control — status, diff, log, blame, branch, commit, checkout, clone |
|
|
29
29
|
| **`db-tools`** | 7 | Database operations — query, schema, tables, count, insert, update, delete (SQLite, PostgreSQL, MySQL) |
|
|
30
30
|
| **`exec-tools`** | 6 | Command execution — run, run shell, background processes, kill, read output |
|
|
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 |
|
|
35
|
+
| **`slack-tools`** | 6 | Slack messaging — post messages, ephemeral messages, channel history, thread replies, reactions |
|
|
34
36
|
| **`diff-tools`** | 3 | Patch operations — create, apply, and preview diffs |
|
|
35
37
|
| **`cloud-tools`** | 3 | Deployments — deploy, status, list (via Netlify) |
|
|
36
38
|
| **`k8s-tools`** | 11 | Kubernetes cluster inspection and management via kubectl |
|
|
39
|
+
| **`skill-tools`** | 4 | Skill management — skill.create, skill.read, skill.update, skill.list |
|
|
37
40
|
| **`mcp-tools`** | 2 | MCP integration — createMcpToolProject, disconnectMcpToolProject |
|
|
38
41
|
|
|
39
42
|
## Quick Start
|
|
@@ -60,7 +63,7 @@ const sdk = await Toolpack.init({
|
|
|
60
63
|
anthropic: {}, // Reads ANTHROPIC_API_KEY from env
|
|
61
64
|
},
|
|
62
65
|
defaultProvider: 'openai',
|
|
63
|
-
tools: true, // Load all
|
|
66
|
+
tools: true, // Load all 100+ built-in tools
|
|
64
67
|
defaultMode: 'agent', // Agent mode with workflow engine
|
|
65
68
|
});
|
|
66
69
|
|
|
@@ -78,7 +81,7 @@ for await (const chunk of sdk.stream({
|
|
|
78
81
|
|
|
79
82
|
// Switch providers on the fly
|
|
80
83
|
const anthropicResponse = await sdk.generate({
|
|
81
|
-
model: '
|
|
84
|
+
model: 'your-model',
|
|
82
85
|
messages: [{ role: 'user', content: 'Hello from Anthropic!' }],
|
|
83
86
|
}, 'anthropic');
|
|
84
87
|
```
|
|
@@ -104,7 +107,7 @@ const sdk = await Toolpack.init({
|
|
|
104
107
|
});
|
|
105
108
|
|
|
106
109
|
const podsResponse = await sdk.generate({
|
|
107
|
-
model: '
|
|
110
|
+
model: 'your-model',
|
|
108
111
|
messages: [
|
|
109
112
|
{
|
|
110
113
|
role: 'user',
|
|
@@ -115,7 +118,7 @@ const podsResponse = await sdk.generate({
|
|
|
115
118
|
console.log(podsResponse.content);
|
|
116
119
|
|
|
117
120
|
const applyResponse = await sdk.generate({
|
|
118
|
-
model: '
|
|
121
|
+
model: 'your-model',
|
|
119
122
|
messages: [
|
|
120
123
|
{
|
|
121
124
|
role: 'user',
|
|
@@ -140,19 +143,20 @@ See `packages/toolpack-sdk/docs/examples/kubernetes-usage.ts` for a complete exa
|
|
|
140
143
|
| **Anthropic** | Claude Sonnet 4, Claude 3.5 Haiku, Claude 3 Opus | No embeddings support |
|
|
141
144
|
| **Google Gemini** | Gemini 2.0 Flash, Gemini 1.5 Pro, Gemini 1.5 Flash | Synthetic tool call IDs |
|
|
142
145
|
| **Ollama** | Auto-discovered from locally pulled models | Capability detection via probing |
|
|
146
|
+
| **OpenRouter** | All models at openrouter.ai (auto-discovered) | Access to 300+ models via OpenAI-compatible API |
|
|
143
147
|
|
|
144
148
|
### Provider Comparison
|
|
145
149
|
|
|
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`) |
|
|
150
|
+
| Capability | OpenAI | Anthropic | Gemini | Ollama | OpenRouter |
|
|
151
|
+
|------------|--------|-----------|--------|--------|------------|
|
|
152
|
+
| Chat completions | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
153
|
+
| Streaming | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
154
|
+
| Tool/function calling | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
155
|
+
| Multi-round tool loop | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
156
|
+
| Embeddings | ✅ | ❌ | ✅ | ✅ | ❌ |
|
|
157
|
+
| Vision/images | ✅ | ✅ | ✅ | ✅ (model-dependent) | ✅ (model-dependent) |
|
|
158
|
+
| Tool name sanitization | ✅ (auto) | ✅ (auto) | ✅ (auto) | ✅ (auto) | ✅ (auto) |
|
|
159
|
+
| Model discovery | Static list | Static list | Static list | Dynamic (`/api/tags` + `/api/show`) | Dynamic (`/models` endpoint) |
|
|
156
160
|
|
|
157
161
|
#### Provider-Specific Notes
|
|
158
162
|
|
|
@@ -201,6 +205,7 @@ const sdk = await Toolpack.init({
|
|
|
201
205
|
See `docs/MCP_INTEGRATION.md` and `docs/examples/mcp-integration-example.ts` for full instructions and best practices.
|
|
202
206
|
- **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
207
|
- **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.
|
|
208
|
+
- **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
209
|
|
|
205
210
|
### Custom Providers
|
|
206
211
|
|
|
@@ -276,8 +281,8 @@ Modes control AI behavior by setting a system prompt, filtering available tools,
|
|
|
276
281
|
|
|
277
282
|
| Mode | Tools | Workflow | Description |
|
|
278
283
|
|------|-------|----------|-------------|
|
|
279
|
-
| **Agent** | All tools |
|
|
280
|
-
| **Coding** | All tools |
|
|
284
|
+
| **Agent** | All tools | Plan-direct execution | Full autonomous access — read, write, execute, browse |
|
|
285
|
+
| **Coding** | All tools | Plan-direct execution | Optimized for coding tasks — minimal text, file operations |
|
|
281
286
|
| **Chat** | Web/HTTP only | Direct execution (no planning) | Conversational assistant with web access |
|
|
282
287
|
|
|
283
288
|
### Custom Modes
|
|
@@ -298,7 +303,6 @@ const reviewMode = createMode({
|
|
|
298
303
|
},
|
|
299
304
|
workflow: {
|
|
300
305
|
planning: { enabled: true },
|
|
301
|
-
steps: { enabled: true, retryOnFailure: true },
|
|
302
306
|
progress: { enabled: true },
|
|
303
307
|
},
|
|
304
308
|
});
|
|
@@ -338,19 +342,17 @@ sdk.cycleMode(); // Cycles through all registered modes
|
|
|
338
342
|
| `blockedTools` | string[] | `[]` | Specific tools to block. Overrides allowed |
|
|
339
343
|
| `blockAllTools` | boolean | `false` | If `true`, disables all tools (pure conversation) |
|
|
340
344
|
| `baseContext` | object/false | `undefined` | Controls working directory and tool category injection |
|
|
341
|
-
| `workflow` | WorkflowConfig | `undefined` | Planning,
|
|
345
|
+
| `workflow` | WorkflowConfig | `undefined` | Planning, execution mode, and progress configuration |
|
|
342
346
|
|
|
343
347
|
## Workflow Engine
|
|
344
348
|
|
|
345
|
-
The workflow engine enables AI agents to plan and execute complex tasks
|
|
349
|
+
The workflow engine enables AI agents to plan and execute complex tasks with parallel tool orchestration.
|
|
346
350
|
|
|
347
351
|
### How It Works
|
|
348
352
|
|
|
349
|
-
1. **Planning** — The AI generates a structured
|
|
350
|
-
2. **Execution** —
|
|
351
|
-
3. **
|
|
352
|
-
4. **Retries** — Failed steps are retried automatically (configurable)
|
|
353
|
-
5. **Progress** — Events are emitted at each stage for UI integration
|
|
353
|
+
1. **Planning** — The AI generates a structured plan from the user's request
|
|
354
|
+
2. **Execution** — The plan is injected as context and executed in a single call with parallel tool orchestration
|
|
355
|
+
3. **Progress** — Events are emitted at each stage for UI integration
|
|
354
356
|
|
|
355
357
|
### Using the Workflow
|
|
356
358
|
|
|
@@ -361,7 +363,7 @@ const sdk = await Toolpack.init({
|
|
|
361
363
|
defaultMode: 'agent', // Agent mode has workflow enabled
|
|
362
364
|
});
|
|
363
365
|
|
|
364
|
-
// Complex tasks are automatically planned
|
|
366
|
+
// Complex tasks are automatically planned (plan-direct) with parallel tool execution
|
|
365
367
|
const result = await sdk.generate('Build me a REST API with user authentication');
|
|
366
368
|
|
|
367
369
|
// Or stream the response
|
|
@@ -383,35 +385,18 @@ const executor = sdk.getWorkflowExecutor();
|
|
|
383
385
|
// Progress updates (ideal for status bars / shimmer text)
|
|
384
386
|
executor.on('workflow:progress', (progress) => {
|
|
385
387
|
// progress.status: 'planning' | 'awaiting_approval' | 'executing' | 'completed' | 'failed'
|
|
386
|
-
// progress.
|
|
387
|
-
|
|
388
|
-
console.log(`[${progress.percentage}%] Step ${progress.currentStep}/${progress.totalSteps}: ${progress.currentStepDescription}`);
|
|
388
|
+
// progress.percentage, progress.currentStepDescription
|
|
389
|
+
console.log(`[${progress.percentage}%] ${progress.currentStepDescription}`);
|
|
389
390
|
});
|
|
390
391
|
|
|
391
|
-
//
|
|
392
|
-
executor.on('workflow:
|
|
393
|
-
console.log(
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
executor.on('workflow:step_complete', (step, plan) => {
|
|
397
|
-
console.log(`Completed: ${step.description}`);
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
executor.on('workflow:step_failed', (step, error, plan) => {
|
|
401
|
-
console.log(`Failed: ${step.description} — ${error.message}`);
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
executor.on('workflow:step_retry', (step, attempt, plan) => {
|
|
405
|
-
console.log(`Retrying: ${step.description} (attempt ${attempt})`);
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
executor.on('workflow:step_added', (step, plan) => {
|
|
409
|
-
console.log(`Dynamic step added: ${step.description}`);
|
|
392
|
+
// Plan created
|
|
393
|
+
executor.on('workflow:plan_created', (plan) => {
|
|
394
|
+
console.log('Plan:', plan.steps.map(s => s.description));
|
|
410
395
|
});
|
|
411
396
|
|
|
412
397
|
// Workflow completion
|
|
413
398
|
executor.on('workflow:completed', (plan, result) => {
|
|
414
|
-
console.log(`Done
|
|
399
|
+
console.log(`Done in ${result.metrics.totalDuration}ms`);
|
|
415
400
|
});
|
|
416
401
|
|
|
417
402
|
executor.on('workflow:failed', (plan, error) => {
|
|
@@ -430,22 +415,10 @@ interface WorkflowConfig {
|
|
|
430
415
|
maxSteps?: number; // Max steps in a plan (default: 20)
|
|
431
416
|
};
|
|
432
417
|
|
|
433
|
-
steps?: {
|
|
434
|
-
enabled: boolean; // Enable step-by-step execution
|
|
435
|
-
retryOnFailure?: boolean; // Retry failed steps (default: true)
|
|
436
|
-
maxRetries?: number; // Max retries per step (default: 3)
|
|
437
|
-
allowDynamicSteps?: boolean; // Allow adding steps during execution
|
|
438
|
-
maxTotalSteps?: number; // Max total steps including dynamic (default: 50)
|
|
439
|
-
};
|
|
440
|
-
|
|
441
418
|
progress?: {
|
|
442
419
|
enabled: boolean; // Emit progress events (default: true)
|
|
443
420
|
reportPercentage?: boolean; // Include completion percentage
|
|
444
421
|
};
|
|
445
|
-
|
|
446
|
-
onFailure?: {
|
|
447
|
-
strategy: 'abort' | 'skip' | 'ask_user';
|
|
448
|
-
};
|
|
449
422
|
}
|
|
450
423
|
```
|
|
451
424
|
|
|
@@ -457,12 +430,12 @@ The SDK provides built-in workflow presets for common use cases:
|
|
|
457
430
|
import { DEFAULT_WORKFLOW, AGENT_WORKFLOW, CODING_WORKFLOW, CHAT_WORKFLOW } from 'toolpack-sdk';
|
|
458
431
|
```
|
|
459
432
|
|
|
460
|
-
| Preset | Planning |
|
|
461
|
-
|
|
462
|
-
| `DEFAULT_WORKFLOW` | Disabled |
|
|
463
|
-
| `AGENT_WORKFLOW` | Enabled (detailed) |
|
|
464
|
-
| `CODING_WORKFLOW` | Enabled (concise) |
|
|
465
|
-
| `CHAT_WORKFLOW` | Disabled |
|
|
433
|
+
| Preset | Planning | Description |
|
|
434
|
+
|--------|----------|-------------|
|
|
435
|
+
| `DEFAULT_WORKFLOW` | Disabled | Direct execution, no planning |
|
|
436
|
+
| `AGENT_WORKFLOW` | Enabled (detailed) | Full autonomous agent with plan-direct execution |
|
|
437
|
+
| `CODING_WORKFLOW` | Enabled (concise) | Minimal prompts optimized for coding tasks |
|
|
438
|
+
| `CHAT_WORKFLOW` | Disabled | Simple conversational mode |
|
|
466
439
|
|
|
467
440
|
### Creating Custom Workflows
|
|
468
441
|
|
|
@@ -485,15 +458,6 @@ Rules:
|
|
|
485
458
|
3. Generate docs in consistent format
|
|
486
459
|
4. Output JSON: {"summary": "...", "steps": [...]}`,
|
|
487
460
|
},
|
|
488
|
-
steps: {
|
|
489
|
-
...AGENT_WORKFLOW.steps,
|
|
490
|
-
stepPrompt: `Execute step {stepNumber}: {stepDescription}
|
|
491
|
-
|
|
492
|
-
Analyze code and write clear documentation.
|
|
493
|
-
Focus on: purpose, parameters, return values, examples.
|
|
494
|
-
|
|
495
|
-
Previous: {previousStepsResults}`,
|
|
496
|
-
},
|
|
497
461
|
};
|
|
498
462
|
|
|
499
463
|
// Use in a custom mode
|
|
@@ -508,23 +472,11 @@ const docMode = createMode({
|
|
|
508
472
|
});
|
|
509
473
|
```
|
|
510
474
|
|
|
511
|
-
### Step Prompt Template Variables
|
|
512
|
-
|
|
513
|
-
When using custom `stepPrompt`, these variables are automatically substituted:
|
|
514
|
-
|
|
515
|
-
| Variable | Description |
|
|
516
|
-
|----------|-------------|
|
|
517
|
-
| `{stepNumber}` | Current step number (1-indexed) |
|
|
518
|
-
| `{planSummary}` | Summary of the overall plan |
|
|
519
|
-
| `{stepDescription}` | Description of the current step |
|
|
520
|
-
| `{previousStepsResults}` | Output from completed steps (truncated to 2000 chars) |
|
|
521
|
-
|
|
522
475
|
### Workflow Prompt Tips
|
|
523
476
|
|
|
524
477
|
- **Keep planning prompts concise** — LLMs perform better with 5-7 clear rules
|
|
525
478
|
- **Use JSON schema examples** — Include the exact expected output format
|
|
526
|
-
- **
|
|
527
|
-
- **Leverage previous results** — The `{previousStepsResults}` variable provides context
|
|
479
|
+
- **Keep prompts task-oriented** — The AI should execute, not discuss
|
|
528
480
|
|
|
529
481
|
## Tool Call Events
|
|
530
482
|
|
|
@@ -548,7 +500,7 @@ client.on('tool:failed', (event) => { /* ... */ });
|
|
|
548
500
|
|
|
549
501
|
## Custom Tools
|
|
550
502
|
|
|
551
|
-
In addition to the
|
|
503
|
+
In addition to the 100+ built-in tools, you can create and register your own custom tool projects using `createToolProject()`:
|
|
552
504
|
|
|
553
505
|
```typescript
|
|
554
506
|
import { Toolpack, createToolProject } from 'toolpack-sdk';
|
|
@@ -644,7 +596,424 @@ const response = await toolpack.chat('How do I configure authentication?');
|
|
|
644
596
|
- **Progress Events**: Track embedding progress with `onEmbeddingProgress`
|
|
645
597
|
- **Metadata Filtering**: Query with filters like `{ hasCode: true, category: 'api' }`
|
|
646
598
|
|
|
647
|
-
See the [Knowledge package README](
|
|
599
|
+
See the [Knowledge package README](./packages/toolpack-knowledge/README.md) for full documentation.
|
|
600
|
+
|
|
601
|
+
## Skills
|
|
602
|
+
|
|
603
|
+
The skills system lets you define **reusable behavioral instructions** in `.skill.md` files and automatically inject them into requests based on message relevance — no agent code changes required.
|
|
604
|
+
|
|
605
|
+
### Quick Start
|
|
606
|
+
|
|
607
|
+
```typescript
|
|
608
|
+
import { Toolpack, createSkillInterceptor, createSkillTools } from 'toolpack-sdk';
|
|
609
|
+
|
|
610
|
+
const toolpack = await Toolpack.init({
|
|
611
|
+
provider: 'anthropic',
|
|
612
|
+
interceptors: [
|
|
613
|
+
createSkillInterceptor({ dir: '.toolpack/skills', maxSkills: 3, minScore: 0.3 }),
|
|
614
|
+
],
|
|
615
|
+
customTools: [
|
|
616
|
+
createSkillTools({ dir: '.toolpack/skills' }),
|
|
617
|
+
],
|
|
618
|
+
});
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
Create a skill file at `.toolpack/skills/code-review.skill.md`:
|
|
622
|
+
|
|
623
|
+
```markdown
|
|
624
|
+
---
|
|
625
|
+
name: code-review
|
|
626
|
+
title: Code Review
|
|
627
|
+
version: 1.0.0
|
|
628
|
+
tags: ["coding", "quality"]
|
|
629
|
+
updated: 2026-01-15T10:00:00.000Z
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## Description
|
|
633
|
+
|
|
634
|
+
Guides the agent through a structured code review process.
|
|
635
|
+
|
|
636
|
+
## Triggers
|
|
637
|
+
|
|
638
|
+
- "review this code"
|
|
639
|
+
- "check my pull request"
|
|
640
|
+
- "code review"
|
|
641
|
+
|
|
642
|
+
## Instructions
|
|
643
|
+
|
|
644
|
+
When reviewing code:
|
|
645
|
+
1. Check for security vulnerabilities first
|
|
646
|
+
2. Verify test coverage exists
|
|
647
|
+
3. Flag naming inconsistencies
|
|
648
|
+
4. Be constructive — suggest improvements, not just problems
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
When a user sends "review this PR", the interceptor automatically injects the `## Instructions` block before the LLM sees the message.
|
|
652
|
+
|
|
653
|
+
### How It Works
|
|
654
|
+
|
|
655
|
+
- **`createSkillInterceptor`** — An SDK interceptor that runs BM25 search on every user message and prepends matching skill instructions as a `<skill-instructions>` block. Validates all files at `Toolpack.init()` time.
|
|
656
|
+
- **`createSkillTools`** — Four LLM-callable tools (`skill.create`, `skill.read`, `skill.update`, `skill.list`) for managing the skill library at runtime.
|
|
657
|
+
|
|
658
|
+
### `createSkillInterceptor` Options
|
|
659
|
+
|
|
660
|
+
| Option | Type | Default | Description |
|
|
661
|
+
|--------|------|---------|-------------|
|
|
662
|
+
| `dir` | string | `.toolpack/skills` | Path to the skill files directory |
|
|
663
|
+
| `maxSkills` | number | `3` | Maximum number of skills injected per message |
|
|
664
|
+
| `minScore` | number | `0.3` | BM25 relevance threshold |
|
|
665
|
+
| `onValidationError` | `'fail'` \| `'warn'` | `'fail'` | How to handle invalid skill files at startup |
|
|
666
|
+
|
|
667
|
+
See the [Skills guide](https://toolpacksdk.com/guides/skills) and [Skill Tools reference](https://toolpacksdk.com/tools/skills) for full documentation.
|
|
668
|
+
|
|
669
|
+
## AI Agents (@toolpack-sdk/agents)
|
|
670
|
+
|
|
671
|
+
Build production-ready AI agents with channels, workflows, and event-driven architecture using the companion `@toolpack-sdk/agents` package:
|
|
672
|
+
|
|
673
|
+
```bash
|
|
674
|
+
npm install @toolpack-sdk/agents
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### What are Agents?
|
|
678
|
+
|
|
679
|
+
Agents are autonomous AI systems that:
|
|
680
|
+
- **Listen** for events from channels (Slack, webhooks, schedules, etc.)
|
|
681
|
+
- **Process** messages using the Toolpack SDK
|
|
682
|
+
- **Execute** tasks with full tool access
|
|
683
|
+
- **Respond** back through the same or different channels
|
|
684
|
+
- **Remember** conversations using knowledge bases
|
|
685
|
+
|
|
686
|
+
### Quick Start
|
|
687
|
+
|
|
688
|
+
```typescript
|
|
689
|
+
import { Toolpack } from 'toolpack-sdk';
|
|
690
|
+
import { BaseAgent, AgentRegistry, SlackChannel } from '@toolpack-sdk/agents';
|
|
691
|
+
|
|
692
|
+
// 1. Create a custom agent
|
|
693
|
+
class SupportAgent extends BaseAgent {
|
|
694
|
+
name = 'support-agent';
|
|
695
|
+
description = 'Customer support agent that answers questions';
|
|
696
|
+
mode = 'chat';
|
|
697
|
+
|
|
698
|
+
async invokeAgent(input) {
|
|
699
|
+
const result = await this.run(input.message);
|
|
700
|
+
await this.sendTo('slack-support', result.output);
|
|
701
|
+
return result;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// 2. Set up channels
|
|
706
|
+
const slackChannel = new SlackChannel({
|
|
707
|
+
name: 'slack-support',
|
|
708
|
+
token: process.env.SLACK_BOT_TOKEN,
|
|
709
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET,
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
// 3. Register agent and channels
|
|
713
|
+
const registry = new AgentRegistry([
|
|
714
|
+
{ agent: SupportAgent, channels: [slackChannel] },
|
|
715
|
+
]);
|
|
716
|
+
|
|
717
|
+
// 4. Initialize Toolpack with agents
|
|
718
|
+
const sdk = await Toolpack.init({
|
|
719
|
+
provider: 'openai',
|
|
720
|
+
tools: true,
|
|
721
|
+
agents: registry,
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// Agents now listen and respond automatically!
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### Built-in Agents
|
|
728
|
+
|
|
729
|
+
The package includes 4 production-ready agents you can use directly or extend:
|
|
730
|
+
|
|
731
|
+
#### ResearchAgent
|
|
732
|
+
```typescript
|
|
733
|
+
import { ResearchAgent } from '@toolpack-sdk/agents';
|
|
734
|
+
|
|
735
|
+
const agent = new ResearchAgent(sdk);
|
|
736
|
+
const result = await agent.invokeAgent({
|
|
737
|
+
message: 'Summarize recent developments in edge AI',
|
|
738
|
+
});
|
|
739
|
+
```
|
|
740
|
+
- **Mode:** `agent`
|
|
741
|
+
- **Tools:** web.search, web.fetch, web.scrape
|
|
742
|
+
- **Use Cases:** Market research, competitive analysis, trend monitoring
|
|
743
|
+
|
|
744
|
+
#### CodingAgent
|
|
745
|
+
```typescript
|
|
746
|
+
import { CodingAgent } from '@toolpack-sdk/agents';
|
|
747
|
+
|
|
748
|
+
const agent = new CodingAgent(sdk);
|
|
749
|
+
const result = await agent.invokeAgent({
|
|
750
|
+
message: 'Refactor the auth module to use the new SDK pattern',
|
|
751
|
+
});
|
|
752
|
+
```
|
|
753
|
+
- **Mode:** `coding`
|
|
754
|
+
- **Tools:** fs.*, coding.*, git.*, exec.*
|
|
755
|
+
- **Use Cases:** Code generation, refactoring, debugging, test writing
|
|
756
|
+
|
|
757
|
+
#### DataAgent
|
|
758
|
+
```typescript
|
|
759
|
+
import { DataAgent } from '@toolpack-sdk/agents';
|
|
760
|
+
|
|
761
|
+
const agent = new DataAgent(sdk);
|
|
762
|
+
const result = await agent.invokeAgent({
|
|
763
|
+
message: 'Generate a weekly summary of signups by region',
|
|
764
|
+
});
|
|
765
|
+
```
|
|
766
|
+
- **Mode:** `agent`
|
|
767
|
+
- **Tools:** db.*, fs.*, http.*
|
|
768
|
+
- **Use Cases:** Database queries, reporting, data analysis, CSV generation
|
|
769
|
+
|
|
770
|
+
#### BrowserAgent
|
|
771
|
+
```typescript
|
|
772
|
+
import { BrowserAgent } from '@toolpack-sdk/agents';
|
|
773
|
+
|
|
774
|
+
const agent = new BrowserAgent(sdk);
|
|
775
|
+
const result = await agent.invokeAgent({
|
|
776
|
+
message: 'Extract all product prices from acme.com/products',
|
|
777
|
+
});
|
|
778
|
+
```
|
|
779
|
+
- **Mode:** `chat`
|
|
780
|
+
- **Tools:** web.fetch, web.screenshot, web.extract_links
|
|
781
|
+
- **Use Cases:** Web scraping, form filling, content extraction
|
|
782
|
+
|
|
783
|
+
### Channels
|
|
784
|
+
|
|
785
|
+
Channels connect agents to the outside world. The package includes 7 built-in channels:
|
|
786
|
+
|
|
787
|
+
#### SlackChannel (Two-way)
|
|
788
|
+
```typescript
|
|
789
|
+
import { SlackChannel } from '@toolpack-sdk/agents';
|
|
790
|
+
|
|
791
|
+
const slack = new SlackChannel({
|
|
792
|
+
name: 'slack-support',
|
|
793
|
+
token: process.env.SLACK_BOT_TOKEN,
|
|
794
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET,
|
|
795
|
+
});
|
|
796
|
+
```
|
|
797
|
+
- ✅ Receives messages from Slack
|
|
798
|
+
- ✅ Replies in threads
|
|
799
|
+
- ✅ Supports `ask()` for human input
|
|
800
|
+
|
|
801
|
+
#### TelegramChannel (Two-way)
|
|
802
|
+
```typescript
|
|
803
|
+
import { TelegramChannel } from '@toolpack-sdk/agents';
|
|
804
|
+
|
|
805
|
+
const telegram = new TelegramChannel({
|
|
806
|
+
name: 'telegram-bot',
|
|
807
|
+
token: process.env.TELEGRAM_BOT_TOKEN,
|
|
808
|
+
});
|
|
809
|
+
```
|
|
810
|
+
- ✅ Receives messages from Telegram
|
|
811
|
+
- ✅ Replies to users
|
|
812
|
+
- ✅ Supports `ask()` for human input
|
|
813
|
+
|
|
814
|
+
#### WebhookChannel (Two-way)
|
|
815
|
+
```typescript
|
|
816
|
+
import { WebhookChannel } from '@toolpack-sdk/agents';
|
|
817
|
+
|
|
818
|
+
const webhook = new WebhookChannel({
|
|
819
|
+
name: 'github-webhook',
|
|
820
|
+
path: '/webhook/github',
|
|
821
|
+
port: 3000,
|
|
822
|
+
secret: process.env.WEBHOOK_SECRET,
|
|
823
|
+
});
|
|
824
|
+
```
|
|
825
|
+
- ✅ Receives HTTP POST webhooks
|
|
826
|
+
- ✅ Signature verification
|
|
827
|
+
- ✅ Supports `ask()` for human input
|
|
828
|
+
|
|
829
|
+
#### ScheduledChannel (Trigger-only)
|
|
830
|
+
```typescript
|
|
831
|
+
import { ScheduledChannel } from '@toolpack-sdk/agents';
|
|
832
|
+
|
|
833
|
+
const scheduler = new ScheduledChannel({
|
|
834
|
+
name: 'daily-report',
|
|
835
|
+
cron: '0 9 * * 1-5', // 9am weekdays
|
|
836
|
+
notify: 'webhook:https://hooks.example.com/daily-report',
|
|
837
|
+
message: 'Generate the daily sales report',
|
|
838
|
+
});
|
|
839
|
+
// For Slack delivery, attach a named SlackChannel to the same agent and
|
|
840
|
+
// call `this.sendTo('<slackChannelName>', output)` from within `run()`.
|
|
841
|
+
```
|
|
842
|
+
- ⏰ Triggers agents on cron schedules
|
|
843
|
+
- ✅ Full cron expression support (ranges, steps, lists, combinations)
|
|
844
|
+
- ❌ No `ask()` support (no human recipient)
|
|
845
|
+
|
|
846
|
+
#### DiscordChannel (Two-way)
|
|
847
|
+
```typescript
|
|
848
|
+
import { DiscordChannel } from '@toolpack-sdk/agents';
|
|
849
|
+
|
|
850
|
+
const discord = new DiscordChannel({
|
|
851
|
+
name: 'discord-bot',
|
|
852
|
+
token: process.env.DISCORD_BOT_TOKEN,
|
|
853
|
+
guildId: 'your-guild-id',
|
|
854
|
+
channelId: 'your-channel-id',
|
|
855
|
+
});
|
|
856
|
+
```
|
|
857
|
+
- ✅ Receives messages from Discord
|
|
858
|
+
- ✅ Replies in threads
|
|
859
|
+
- ✅ Supports `ask()` for human input
|
|
860
|
+
|
|
861
|
+
#### EmailChannel (Outbound-only)
|
|
862
|
+
```typescript
|
|
863
|
+
import { EmailChannel } from '@toolpack-sdk/agents';
|
|
864
|
+
|
|
865
|
+
const email = new EmailChannel({
|
|
866
|
+
name: 'email-alerts',
|
|
867
|
+
from: 'bot@acme.com',
|
|
868
|
+
to: 'team@acme.com',
|
|
869
|
+
smtp: {
|
|
870
|
+
host: 'smtp.gmail.com',
|
|
871
|
+
port: 587,
|
|
872
|
+
auth: { user: 'bot@acme.com', pass: process.env.SMTP_PASSWORD },
|
|
873
|
+
},
|
|
874
|
+
});
|
|
875
|
+
```
|
|
876
|
+
- 📧 Sends emails via SMTP
|
|
877
|
+
- ❌ No `ask()` support (outbound-only)
|
|
878
|
+
|
|
879
|
+
#### SMSChannel (Configurable)
|
|
880
|
+
```typescript
|
|
881
|
+
import { SMSChannel } from '@toolpack-sdk/agents';
|
|
882
|
+
|
|
883
|
+
// Two-way with webhook
|
|
884
|
+
const sms = new SMSChannel({
|
|
885
|
+
name: 'sms-alerts',
|
|
886
|
+
accountSid: process.env.TWILIO_ACCOUNT_SID,
|
|
887
|
+
authToken: process.env.TWILIO_AUTH_TOKEN,
|
|
888
|
+
from: '+1234567890',
|
|
889
|
+
webhookPath: '/sms/webhook', // Enables two-way
|
|
890
|
+
port: 3000,
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
// Outbound-only
|
|
894
|
+
const smsOutbound = new SMSChannel({
|
|
895
|
+
name: 'sms-notifications',
|
|
896
|
+
accountSid: process.env.TWILIO_ACCOUNT_SID,
|
|
897
|
+
authToken: process.env.TWILIO_AUTH_TOKEN,
|
|
898
|
+
from: '+1234567890',
|
|
899
|
+
to: '+0987654321', // Fixed recipient
|
|
900
|
+
});
|
|
901
|
+
```
|
|
902
|
+
- 📱 Twilio SMS integration
|
|
903
|
+
- ✅ Two-way when `webhookPath` is set
|
|
904
|
+
- ❌ Outbound-only without webhook
|
|
905
|
+
|
|
906
|
+
### Agent Lifecycle & Events
|
|
907
|
+
|
|
908
|
+
Agents emit events at each stage of execution:
|
|
909
|
+
|
|
910
|
+
```typescript
|
|
911
|
+
const agent = new MyAgent(sdk);
|
|
912
|
+
|
|
913
|
+
agent.on('agent:start', (input) => {
|
|
914
|
+
console.log('Agent started:', input.message);
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
agent.on('agent:complete', (result) => {
|
|
918
|
+
console.log('Agent completed:', result.output);
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
agent.on('agent:error', (error) => {
|
|
922
|
+
console.error('Agent error:', error);
|
|
923
|
+
});
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
### Knowledge Integration
|
|
927
|
+
|
|
928
|
+
Agents can use knowledge bases for conversation memory and RAG:
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
import { Knowledge, MemoryProvider, OllamaEmbedder } from '@toolpack-sdk/knowledge';
|
|
932
|
+
import { BaseAgent } from '@toolpack-sdk/agents';
|
|
933
|
+
|
|
934
|
+
class SmartAgent extends BaseAgent {
|
|
935
|
+
name = 'smart-agent';
|
|
936
|
+
description = 'Agent with memory';
|
|
937
|
+
mode = 'chat';
|
|
938
|
+
|
|
939
|
+
constructor(toolpack) {
|
|
940
|
+
super(toolpack);
|
|
941
|
+
// Set up knowledge base
|
|
942
|
+
this.knowledge = await Knowledge.create({
|
|
943
|
+
provider: new MemoryProvider(),
|
|
944
|
+
embedder: new OllamaEmbedder({ model: 'nomic-embed-text' }),
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
async invokeAgent(input) {
|
|
949
|
+
// Conversation history is automatically loaded from knowledge
|
|
950
|
+
const result = await this.run(input.message);
|
|
951
|
+
return result;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
### Multi-Channel Routing
|
|
957
|
+
|
|
958
|
+
Agents can send output to different channels:
|
|
959
|
+
|
|
960
|
+
```typescript
|
|
961
|
+
class MultiChannelAgent extends BaseAgent {
|
|
962
|
+
name = 'multi-agent';
|
|
963
|
+
description = 'Routes to multiple channels';
|
|
964
|
+
mode = 'agent';
|
|
965
|
+
|
|
966
|
+
async invokeAgent(input) {
|
|
967
|
+
const result = await this.run(input.message);
|
|
968
|
+
|
|
969
|
+
// Send to multiple channels
|
|
970
|
+
await this.sendTo('slack:#general', result.output);
|
|
971
|
+
await this.sendTo('email-team', result.output);
|
|
972
|
+
await this.sendTo('sms-alerts', 'Task completed!');
|
|
973
|
+
|
|
974
|
+
return result;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
### Extending Built-in Agents
|
|
980
|
+
|
|
981
|
+
```typescript
|
|
982
|
+
import { ResearchAgent } from '@toolpack-sdk/agents';
|
|
983
|
+
|
|
984
|
+
class FintechResearchAgent extends ResearchAgent {
|
|
985
|
+
systemPrompt = `You are a research agent focused on fintech.
|
|
986
|
+
Always cite sources and flag regulatory implications.`;
|
|
987
|
+
provider = 'anthropic';
|
|
988
|
+
model = 'your-model';
|
|
989
|
+
|
|
990
|
+
async onComplete(result) {
|
|
991
|
+
// Store research in knowledge base
|
|
992
|
+
if (this.knowledge) {
|
|
993
|
+
await this.knowledge.add(result.output, {
|
|
994
|
+
category: 'research',
|
|
995
|
+
topic: 'fintech',
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// Send to Slack
|
|
1000
|
+
await this.sendTo('slack-research', result.output);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
### Features
|
|
1006
|
+
|
|
1007
|
+
- ✅ **7 Built-in Channels** — Slack, Telegram, Discord, Email, SMS, Webhook, Scheduled
|
|
1008
|
+
- ✅ **4 Built-in Agents** — Research, Coding, Data, Browser
|
|
1009
|
+
- ✅ **Event-Driven** — Full lifecycle events for monitoring
|
|
1010
|
+
- ✅ **Knowledge Integration** — Conversation memory and RAG
|
|
1011
|
+
- ✅ **Multi-Channel Routing** — Send to any registered channel
|
|
1012
|
+
- ✅ **Human-in-the-Loop** — `ask()` support for two-way channels
|
|
1013
|
+
- ✅ **Type-Safe** — Full TypeScript support
|
|
1014
|
+
- ✅ **199 Tests Passing** — Production-ready
|
|
1015
|
+
|
|
1016
|
+
See the [Agents package README](./packages/toolpack-agents/README.md) for full documentation.
|
|
648
1017
|
|
|
649
1018
|
## Multimodal Support
|
|
650
1019
|
|
|
@@ -704,6 +1073,7 @@ const response = await sdk.generate({
|
|
|
704
1073
|
export OPENAI_API_KEY="sk-..."
|
|
705
1074
|
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
706
1075
|
export GOOGLE_GENERATIVE_AI_KEY="AIza..."
|
|
1076
|
+
export OPENROUTER_API_KEY="sk-or-..."
|
|
707
1077
|
|
|
708
1078
|
# SDK logging (override — prefer toolpack.config.json instead)
|
|
709
1079
|
export TOOLPACK_SDK_LOG_FILE="./toolpack.log" # Log file path (also enables logging)
|
|
@@ -926,6 +1296,7 @@ interface CompletionRequest {
|
|
|
926
1296
|
temperature?: number;
|
|
927
1297
|
max_tokens?: number;
|
|
928
1298
|
tools?: ToolCallRequest[];
|
|
1299
|
+
requestTools?: RequestToolDefinition[]; // Request-scoped tools
|
|
929
1300
|
tool_choice?: 'auto' | 'none' | 'required';
|
|
930
1301
|
}
|
|
931
1302
|
|
|
@@ -956,6 +1327,115 @@ interface ProviderModelInfo {
|
|
|
956
1327
|
}
|
|
957
1328
|
```
|
|
958
1329
|
|
|
1330
|
+
### Request-Scoped Tools
|
|
1331
|
+
|
|
1332
|
+
Request-scoped tools are dynamic tools attached to a single completion request. Unlike globally registered tools in the ToolRegistry, they:
|
|
1333
|
+
|
|
1334
|
+
- **Don't pollute the shared registry** — Each request can have its own tools
|
|
1335
|
+
- **Can close over request-specific state** — e.g., `conversationId`, user context
|
|
1336
|
+
- **Are safe for multi-agent/multi-request usage** — No cross-request contamination
|
|
1337
|
+
- **Execute through the same SDK orchestration** — Events, logging, HITL all work
|
|
1338
|
+
|
|
1339
|
+
#### Built-in Request-Scoped Tools
|
|
1340
|
+
|
|
1341
|
+
**Knowledge Tools** (when `knowledge` is configured):
|
|
1342
|
+
- `knowledge_search` — Search the knowledge base for relevant information
|
|
1343
|
+
- `knowledge_add` — Add new content to the knowledge base at runtime
|
|
1344
|
+
|
|
1345
|
+
**Conversation Tools** (when using `ConversationHistory`):
|
|
1346
|
+
- `conversation_search` — Search conversation history for past messages
|
|
1347
|
+
|
|
1348
|
+
#### Creating Custom Request Tools
|
|
1349
|
+
|
|
1350
|
+
```typescript
|
|
1351
|
+
import { RequestToolDefinition, ConversationHistory } from 'toolpack-sdk';
|
|
1352
|
+
|
|
1353
|
+
// Example: Session-specific calculator
|
|
1354
|
+
const createCalculatorTool = (sessionId: string): RequestToolDefinition => ({
|
|
1355
|
+
name: 'calculate',
|
|
1356
|
+
displayName: 'Calculator',
|
|
1357
|
+
description: 'Perform mathematical calculations',
|
|
1358
|
+
category: 'math',
|
|
1359
|
+
parameters: {
|
|
1360
|
+
type: 'object',
|
|
1361
|
+
properties: {
|
|
1362
|
+
expression: { type: 'string', description: 'Math expression to evaluate' },
|
|
1363
|
+
},
|
|
1364
|
+
required: ['expression'],
|
|
1365
|
+
},
|
|
1366
|
+
execute: async (args) => {
|
|
1367
|
+
// Can safely close over sessionId
|
|
1368
|
+
console.log(`Session ${sessionId}: calculating ${args.expression}`);
|
|
1369
|
+
|
|
1370
|
+
// Simple eval (use a proper math library in production)
|
|
1371
|
+
const result = eval(args.expression);
|
|
1372
|
+
return { result, sessionId };
|
|
1373
|
+
},
|
|
1374
|
+
});
|
|
1375
|
+
|
|
1376
|
+
// Use in a request
|
|
1377
|
+
const result = await sdk.generate({
|
|
1378
|
+
messages: [{ role: 'user', content: 'What is 15 * 23?' }],
|
|
1379
|
+
model: 'gpt-4',
|
|
1380
|
+
requestTools: [createCalculatorTool('user-123')],
|
|
1381
|
+
});
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
#### Using ConversationHistory with Request Tools
|
|
1385
|
+
|
|
1386
|
+
```typescript
|
|
1387
|
+
import { ConversationHistory } from 'toolpack-sdk';
|
|
1388
|
+
|
|
1389
|
+
const history = new ConversationHistory('./chat.db');
|
|
1390
|
+
|
|
1391
|
+
// Add some messages
|
|
1392
|
+
await history.addUserMessage('conv-1', 'What is the API rate limit?');
|
|
1393
|
+
await history.addAssistantMessage('conv-1', 'The rate limit is 100 requests per minute.');
|
|
1394
|
+
|
|
1395
|
+
// Use conversation search in a request
|
|
1396
|
+
const result = await sdk.generate({
|
|
1397
|
+
messages: [
|
|
1398
|
+
{ role: 'user', content: 'What did we discuss about rate limits?' }
|
|
1399
|
+
],
|
|
1400
|
+
model: 'gpt-4',
|
|
1401
|
+
requestTools: [
|
|
1402
|
+
history.toTool('conv-1'), // Scoped to conversation 'conv-1'
|
|
1403
|
+
],
|
|
1404
|
+
});
|
|
1405
|
+
|
|
1406
|
+
// AI can now call conversation_search to find the earlier discussion
|
|
1407
|
+
```
|
|
1408
|
+
|
|
1409
|
+
#### Request Tools vs Registry Tools
|
|
1410
|
+
|
|
1411
|
+
| Feature | Request Tools | Registry Tools |
|
|
1412
|
+
|---------|---------------|----------------|
|
|
1413
|
+
| **Scope** | Single request | All requests |
|
|
1414
|
+
| **State** | Can close over request state | Stateless |
|
|
1415
|
+
| **Registration** | Per-request via `requestTools` | Global via `ToolRegistry` |
|
|
1416
|
+
| **Use Case** | Dynamic, stateful tools | Reusable, static tools |
|
|
1417
|
+
| **Priority** | Higher (checked first) | Lower |
|
|
1418
|
+
| **Examples** | `conversation_search`, `knowledge_add` | `fs.read_file`, `web.search` |
|
|
1419
|
+
|
|
1420
|
+
#### Automatic Guidance Injection
|
|
1421
|
+
|
|
1422
|
+
When request-scoped tools are present, the SDK automatically injects usage guidance into the system prompt:
|
|
1423
|
+
|
|
1424
|
+
```
|
|
1425
|
+
Knowledge Base:
|
|
1426
|
+
- Use `knowledge_search` when you need factual or domain-specific information.
|
|
1427
|
+
- Use `knowledge_add` when you learn durable information that should be saved.
|
|
1428
|
+
|
|
1429
|
+
Conversation History:
|
|
1430
|
+
- Only recent messages may be present in context.
|
|
1431
|
+
- Use `conversation_search` to find details from earlier in this conversation.
|
|
1432
|
+
```
|
|
1433
|
+
|
|
1434
|
+
This guidance is:
|
|
1435
|
+
- **Per-request** — Only injected when tools are actually present
|
|
1436
|
+
- **Derived from effective tool set** — Reflects the actual tools available
|
|
1437
|
+
- **Idempotent** — Won't duplicate if already present
|
|
1438
|
+
|
|
959
1439
|
## Error Handling
|
|
960
1440
|
|
|
961
1441
|
The SDK provides typed error classes for common failure scenarios:
|
|
@@ -1008,21 +1488,25 @@ toolpack-sdk/
|
|
|
1008
1488
|
│ │ ├── openai/ # OpenAI adapter
|
|
1009
1489
|
│ │ ├── anthropic/ # Anthropic adapter
|
|
1010
1490
|
│ │ ├── gemini/ # Google Gemini adapter
|
|
1491
|
+
│ │ ├── openrouter/ # OpenRouter adapter (OpenAI-compatible, dynamic model discovery)
|
|
1011
1492
|
│ │ └── ollama/ # Ollama adapter + provider (auto-discovery)
|
|
1012
1493
|
│ ├── modes/ # Mode system (Agent, Chat, createMode)
|
|
1013
|
-
│ ├── workflows/ # Workflow engine (planner,
|
|
1014
|
-
│ ├── tools/ #
|
|
1494
|
+
│ ├── workflows/ # Workflow engine (planner, executor, progress)
|
|
1495
|
+
│ ├── tools/ # 100+ built-in tools + registry + router + BM25 search
|
|
1015
1496
|
│ │ ├── fs-tools/ # File system (18 tools)
|
|
1016
1497
|
│ │ ├── coding-tools/ # Code analysis (12 tools)
|
|
1017
|
-
│ │ ├── git-tools/ # Git operations (
|
|
1018
|
-
│ │ ├── db-tools/ # Database operations (
|
|
1498
|
+
│ │ ├── git-tools/ # Git operations (10 tools)
|
|
1499
|
+
│ │ ├── db-tools/ # Database operations (7 tools)
|
|
1019
1500
|
│ │ ├── exec-tools/ # Command execution (6 tools)
|
|
1020
1501
|
│ │ ├── http-tools/ # HTTP requests (5 tools)
|
|
1021
|
-
│ │ ├── web-tools/ # Web interaction (
|
|
1502
|
+
│ │ ├── web-tools/ # Web interaction (9 tools)
|
|
1022
1503
|
│ │ ├── system-tools/ # System info (5 tools)
|
|
1504
|
+
│ │ ├── github-tools/ # GitHub API (9 tools)
|
|
1505
|
+
│ │ ├── slack-tools/ # Slack messaging (6 tools)
|
|
1023
1506
|
│ │ ├── diff-tools/ # Patch operations (3 tools)
|
|
1024
1507
|
│ │ ├── cloud-tools/ # Deployments (3 tools)
|
|
1025
1508
|
│ │ ├── k8s-tools/ # Kubernetes management (11 tools)
|
|
1509
|
+
│ │ ├── skill-tools/ # Skill management (4 tools)
|
|
1026
1510
|
│ │ ├── registry.ts # Tool registry and loading
|
|
1027
1511
|
│ │ ├── router.ts # Tool routing and filtering
|
|
1028
1512
|
│ │ └── search/ # BM25 tool discovery engine (internal)
|
|
@@ -1037,9 +1521,9 @@ toolpack-sdk/
|
|
|
1037
1521
|
|
|
1038
1522
|
**Current Version:** 0.1.0
|
|
1039
1523
|
|
|
1040
|
-
- ✓ **
|
|
1041
|
-
- ✓ **
|
|
1042
|
-
- ✓ **Workflow Engine** — AI-driven planning,
|
|
1524
|
+
- ✓ **5 Built-in Providers** — OpenAI, Anthropic, Gemini, Ollama, OpenRouter (+ custom provider API)
|
|
1525
|
+
- ✓ **100+ Built-in Tools** — fs, exec, git, diff, web, coding, db, cloud, http, system, Kubernetes, GitHub, Slack, Skills
|
|
1526
|
+
- ✓ **Workflow Engine** — AI-driven planning, plan-direct execution, parallel tool orchestration, progress events
|
|
1043
1527
|
- ✓ **Mode System** — Agent, Coding, Chat, and custom modes via `createMode()` with `blockAllTools` support
|
|
1044
1528
|
- ✓ **Tool Search** — BM25-based on-demand tool discovery for large tool libraries
|
|
1045
1529
|
- ✓ **545 Tests** passing across 81 test files
|