agent-toolbelt 0.1.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 +182 -0
- package/dist/index.d.mts +201 -0
- package/dist/index.d.ts +201 -0
- package/dist/index.js +97 -0
- package/dist/index.mjs +70 -0
- package/dist/langchain.d.mts +22 -0
- package/dist/langchain.d.ts +22 -0
- package/dist/langchain.js +173 -0
- package/dist/langchain.mjs +148 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# agent-toolbelt
|
|
2
|
+
|
|
3
|
+
Official SDK for [Agent Toolbelt](https://agent-toolbelt-production.up.railway.app) — a suite of focused API tools for AI agents and developers.
|
|
4
|
+
|
|
5
|
+
**Typed client + LangChain tool wrappers** for schema generation, text extraction, token counting, CSV conversion, Markdown conversion, URL metadata, regex building, cron expressions, address normalization, and color palette generation.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install agent-toolbelt
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Get an API key
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
curl -X POST https://agent-toolbelt-production.up.railway.app/api/clients/register \
|
|
17
|
+
-H "Content-Type: application/json" \
|
|
18
|
+
-d '{"email": "you@example.com"}'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Typed Client
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { AgentToolbelt } from "agent-toolbelt";
|
|
27
|
+
|
|
28
|
+
const client = new AgentToolbelt({ apiKey: process.env.AGENT_TOOLBELT_KEY! });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Text Extractor
|
|
32
|
+
|
|
33
|
+
Pull structured data out of raw text — no regex required.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const result = await client.textExtractor({
|
|
37
|
+
text: "Contact Sarah at sarah@acme.com or (555) 867-5309. Budget: $12,500.",
|
|
38
|
+
extractors: ["emails", "phone_numbers", "currencies"],
|
|
39
|
+
});
|
|
40
|
+
// result.extracted.emails → ["sarah@acme.com"]
|
|
41
|
+
// result.extracted.phone_numbers → ["+15558675309"]
|
|
42
|
+
// result.extracted.currencies → ["$12,500"]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Token Counter
|
|
46
|
+
|
|
47
|
+
Never get surprised by context window costs again.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const result = await client.tokenCounter({
|
|
51
|
+
text: longDocument,
|
|
52
|
+
models: ["gpt-4o", "claude-3-5-sonnet", "gpt-3.5-turbo"],
|
|
53
|
+
});
|
|
54
|
+
// result.results["gpt-4o"].tokens → 1842
|
|
55
|
+
// result.results["gpt-4o"].estimatedCost.input → 0.0000092 (USD)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Schema Generator
|
|
59
|
+
|
|
60
|
+
Describe your data in English, get back a schema.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const result = await client.schemaGenerator({
|
|
64
|
+
description: "a SaaS user with name, email, plan tier, and usage limits",
|
|
65
|
+
format: "typescript",
|
|
66
|
+
});
|
|
67
|
+
// result.schema → full TypeScript interface
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### CSV to JSON
|
|
71
|
+
|
|
72
|
+
Drop in CSV, get back typed JSON.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const result = await client.csvToJson({
|
|
76
|
+
csv: rawCsvString,
|
|
77
|
+
typeCast: true, // "true" → true, "42" → 42, "" → null
|
|
78
|
+
});
|
|
79
|
+
// result.rows → [{ name: "Alice", age: 30, active: true }, ...]
|
|
80
|
+
// result.columnTypes → { name: "string", age: "number", active: "boolean" }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Markdown Converter
|
|
84
|
+
|
|
85
|
+
Clean up HTML for LLM consumption.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
const result = await client.markdownConverter({
|
|
89
|
+
content: scrapedHtml,
|
|
90
|
+
from: "html",
|
|
91
|
+
to: "markdown",
|
|
92
|
+
});
|
|
93
|
+
// result.output → clean Markdown without tags
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### URL Metadata
|
|
97
|
+
|
|
98
|
+
Enrich any link with context.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const result = await client.urlMetadata({ url: "https://example.com/article" });
|
|
102
|
+
// result.metadata.title → "Article Title"
|
|
103
|
+
// result.metadata.description → "Meta description..."
|
|
104
|
+
// result.metadata.og → { image: "...", type: "article" }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Other tools
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
// Natural language → cron expression
|
|
111
|
+
await client.cronBuilder({ description: "every weekday at 9am", timezone: "America/New_York" });
|
|
112
|
+
|
|
113
|
+
// Natural language → regex with code snippets
|
|
114
|
+
await client.regexBuilder({ description: "US phone numbers", testStrings: ["555-867-5309"] });
|
|
115
|
+
|
|
116
|
+
// Normalize messy US addresses to USPS format
|
|
117
|
+
await client.addressNormalizer({ address: "123 main st apt 4b, springfield, il 62701" });
|
|
118
|
+
|
|
119
|
+
// Generate color palettes from descriptions or hex colors
|
|
120
|
+
await client.colorPalette({ description: "calm fintech blue", count: 5 });
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## LangChain Integration
|
|
126
|
+
|
|
127
|
+
Use Agent Toolbelt tools directly in LangChain agents and chains.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { AgentToolbelt } from "agent-toolbelt";
|
|
131
|
+
import { createLangChainTools } from "agent-toolbelt/langchain";
|
|
132
|
+
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
133
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
134
|
+
|
|
135
|
+
const client = new AgentToolbelt({ apiKey: process.env.AGENT_TOOLBELT_KEY! });
|
|
136
|
+
const tools = createLangChainTools(client);
|
|
137
|
+
|
|
138
|
+
const agent = createReactAgent({
|
|
139
|
+
llm: new ChatOpenAI({ model: "gpt-4o" }),
|
|
140
|
+
tools,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const result = await agent.invoke({
|
|
144
|
+
messages: [{ role: "user", content: "Extract all emails and phone numbers from this text: ..." }],
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Available LangChain tools
|
|
149
|
+
|
|
150
|
+
| Tool name | Description |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `extract_from_text` | Extract emails, URLs, phones, dates, currencies, addresses, names from text |
|
|
153
|
+
| `count_tokens` | Count tokens and estimate cost across LLM models |
|
|
154
|
+
| `generate_schema` | Generate JSON Schema / TypeScript / Zod from a description |
|
|
155
|
+
| `csv_to_json` | Convert CSV to typed JSON with auto type casting |
|
|
156
|
+
| `convert_markdown` | Convert HTML ↔ Markdown |
|
|
157
|
+
| `fetch_url_metadata` | Get title, description, OG tags, favicon from a URL |
|
|
158
|
+
| `build_regex` | Build and test regex patterns from natural language |
|
|
159
|
+
| `build_cron` | Convert schedule descriptions to cron expressions |
|
|
160
|
+
| `normalize_address` | Normalize US addresses to USPS format |
|
|
161
|
+
| `generate_color_palette` | Generate color palettes with WCAG scores and CSS variables |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## All tools
|
|
166
|
+
|
|
167
|
+
| Tool | Pricing |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `schema-generator` | $0.001 / call |
|
|
170
|
+
| `text-extractor` | $0.0005 / call |
|
|
171
|
+
| `token-counter` | $0.0001 / call |
|
|
172
|
+
| `csv-to-json` | $0.0005 / call |
|
|
173
|
+
| `markdown-converter` | $0.0005 / call |
|
|
174
|
+
| `url-metadata` | $0.001 / call |
|
|
175
|
+
| `regex-builder` | $0.0005 / call |
|
|
176
|
+
| `cron-builder` | $0.0005 / call |
|
|
177
|
+
| `address-normalizer` | $0.0005 / call |
|
|
178
|
+
| `color-palette` | $0.0005 / call |
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
interface AgentToolbeltOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
interface SchemaGeneratorResult {
|
|
6
|
+
schema: object | string;
|
|
7
|
+
format: "json_schema" | "zod" | "typescript";
|
|
8
|
+
}
|
|
9
|
+
interface TextExtractorResult {
|
|
10
|
+
extracted: Record<string, string[]>;
|
|
11
|
+
summary: {
|
|
12
|
+
totalItemsFound: number;
|
|
13
|
+
byType: Record<string, number>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
interface TokenCountResult {
|
|
17
|
+
characterCount: number;
|
|
18
|
+
wordCount: number;
|
|
19
|
+
results: Record<string, {
|
|
20
|
+
tokens: number;
|
|
21
|
+
encoding: string;
|
|
22
|
+
approximate: boolean;
|
|
23
|
+
estimatedCost?: {
|
|
24
|
+
input: number;
|
|
25
|
+
output: number;
|
|
26
|
+
currency: string;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
supportedModels: string[];
|
|
30
|
+
}
|
|
31
|
+
interface CsvToJsonResult {
|
|
32
|
+
success: boolean;
|
|
33
|
+
rows: Record<string, unknown>[];
|
|
34
|
+
headers: string[];
|
|
35
|
+
rowCount: number;
|
|
36
|
+
totalRows: number;
|
|
37
|
+
columnCount: number;
|
|
38
|
+
columnTypes: Record<string, string>;
|
|
39
|
+
detectedDelimiter?: string;
|
|
40
|
+
truncated?: boolean;
|
|
41
|
+
}
|
|
42
|
+
interface MarkdownConverterResult {
|
|
43
|
+
output: string;
|
|
44
|
+
from: string;
|
|
45
|
+
to: string;
|
|
46
|
+
inputLength: number;
|
|
47
|
+
outputLength: number;
|
|
48
|
+
}
|
|
49
|
+
interface UrlMetadataResult {
|
|
50
|
+
url: string;
|
|
51
|
+
finalUrl: string;
|
|
52
|
+
statusCode: number | null;
|
|
53
|
+
error?: string;
|
|
54
|
+
metadata: {
|
|
55
|
+
title: string | null;
|
|
56
|
+
description: string | null;
|
|
57
|
+
favicon: string | null;
|
|
58
|
+
canonical: string | null;
|
|
59
|
+
author: string | null;
|
|
60
|
+
themeColor: string | null;
|
|
61
|
+
publishedTime: string | null;
|
|
62
|
+
modifiedTime: string | null;
|
|
63
|
+
og: Record<string, string>;
|
|
64
|
+
twitter: Record<string, string>;
|
|
65
|
+
} | null;
|
|
66
|
+
}
|
|
67
|
+
interface RegexBuilderResult {
|
|
68
|
+
pattern: string;
|
|
69
|
+
flags: string;
|
|
70
|
+
regexLiteral: string;
|
|
71
|
+
description: string;
|
|
72
|
+
category: string;
|
|
73
|
+
codeSnippets: {
|
|
74
|
+
javascript: string;
|
|
75
|
+
python: string;
|
|
76
|
+
typescript: string;
|
|
77
|
+
};
|
|
78
|
+
testResults?: Array<{
|
|
79
|
+
input: string;
|
|
80
|
+
matched: boolean;
|
|
81
|
+
matches: string[];
|
|
82
|
+
}>;
|
|
83
|
+
}
|
|
84
|
+
interface CronBuilderResult {
|
|
85
|
+
expression: string;
|
|
86
|
+
humanReadable: string;
|
|
87
|
+
timezone: string;
|
|
88
|
+
fields: Record<string, string>;
|
|
89
|
+
nextRuns: string[];
|
|
90
|
+
warnings: string[];
|
|
91
|
+
}
|
|
92
|
+
interface AddressNormalizerResult {
|
|
93
|
+
original: string;
|
|
94
|
+
normalized: string;
|
|
95
|
+
confidence: "high" | "medium" | "low";
|
|
96
|
+
components?: {
|
|
97
|
+
streetNumber?: string;
|
|
98
|
+
preDirectional?: string;
|
|
99
|
+
streetName?: string;
|
|
100
|
+
streetType?: string;
|
|
101
|
+
postDirectional?: string;
|
|
102
|
+
secondaryUnit?: string;
|
|
103
|
+
secondaryNumber?: string;
|
|
104
|
+
city?: string;
|
|
105
|
+
state?: string;
|
|
106
|
+
zip?: string;
|
|
107
|
+
zip4?: string;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
interface ColorPaletteResult {
|
|
111
|
+
paletteName: string;
|
|
112
|
+
paletteLabel: string;
|
|
113
|
+
colors: Array<{
|
|
114
|
+
index: number;
|
|
115
|
+
name: string;
|
|
116
|
+
hex: string;
|
|
117
|
+
rgb?: string;
|
|
118
|
+
hsl?: string;
|
|
119
|
+
wcag: {
|
|
120
|
+
contrastOnWhite: number;
|
|
121
|
+
contrastOnBlack: number;
|
|
122
|
+
gradeOnWhite: string;
|
|
123
|
+
gradeOnBlack: string;
|
|
124
|
+
};
|
|
125
|
+
}>;
|
|
126
|
+
css: string;
|
|
127
|
+
swatches: string;
|
|
128
|
+
}
|
|
129
|
+
declare class AgentToolbelt {
|
|
130
|
+
private apiKey;
|
|
131
|
+
private baseUrl;
|
|
132
|
+
constructor({ apiKey, baseUrl }: AgentToolbeltOptions);
|
|
133
|
+
private call;
|
|
134
|
+
/** Generate JSON Schema, TypeScript, or Zod from a plain-English description */
|
|
135
|
+
schemaGenerator(input: {
|
|
136
|
+
description: string;
|
|
137
|
+
format?: "json_schema" | "zod" | "typescript";
|
|
138
|
+
strict?: boolean;
|
|
139
|
+
}): Promise<SchemaGeneratorResult>;
|
|
140
|
+
/** Extract emails, URLs, phone numbers, dates, currencies, addresses, or names from text */
|
|
141
|
+
textExtractor(input: {
|
|
142
|
+
text: string;
|
|
143
|
+
extractors: Array<"emails" | "urls" | "phone_numbers" | "dates" | "currencies" | "addresses" | "names" | "json_blocks">;
|
|
144
|
+
deduplicate?: boolean;
|
|
145
|
+
}): Promise<TextExtractorResult>;
|
|
146
|
+
/** Count tokens across multiple LLM models with cost estimates */
|
|
147
|
+
tokenCounter(input: {
|
|
148
|
+
text: string;
|
|
149
|
+
models?: string[];
|
|
150
|
+
}): Promise<TokenCountResult>;
|
|
151
|
+
/** Convert CSV to typed JSON with auto-delimiter detection and type casting */
|
|
152
|
+
csvToJson(input: {
|
|
153
|
+
csv: string;
|
|
154
|
+
delimiter?: "auto" | "," | ";" | "\t" | "|";
|
|
155
|
+
hasHeader?: boolean;
|
|
156
|
+
typeCast?: boolean;
|
|
157
|
+
limit?: number;
|
|
158
|
+
skipEmptyRows?: boolean;
|
|
159
|
+
}): Promise<CsvToJsonResult>;
|
|
160
|
+
/** Convert HTML to Markdown or Markdown to HTML */
|
|
161
|
+
markdownConverter(input: {
|
|
162
|
+
content: string;
|
|
163
|
+
from: "html" | "markdown";
|
|
164
|
+
to: "html" | "markdown";
|
|
165
|
+
options?: {
|
|
166
|
+
headingStyle?: "atx" | "setext";
|
|
167
|
+
bulletListMarker?: "-" | "*" | "+";
|
|
168
|
+
codeBlockStyle?: "fenced" | "indented";
|
|
169
|
+
};
|
|
170
|
+
}): Promise<MarkdownConverterResult>;
|
|
171
|
+
/** Fetch a URL and extract title, description, OG tags, favicon, and more */
|
|
172
|
+
urlMetadata(input: {
|
|
173
|
+
url: string;
|
|
174
|
+
timeout?: number;
|
|
175
|
+
}): Promise<UrlMetadataResult>;
|
|
176
|
+
/** Build and test regular expressions from natural language */
|
|
177
|
+
regexBuilder(input: {
|
|
178
|
+
description: string;
|
|
179
|
+
testStrings?: string[];
|
|
180
|
+
flags?: string;
|
|
181
|
+
}): Promise<RegexBuilderResult>;
|
|
182
|
+
/** Convert a natural language schedule to a cron expression */
|
|
183
|
+
cronBuilder(input: {
|
|
184
|
+
description: string;
|
|
185
|
+
timezone?: string;
|
|
186
|
+
}): Promise<CronBuilderResult>;
|
|
187
|
+
/** Normalize a US address to USPS format with component parsing */
|
|
188
|
+
addressNormalizer(input: {
|
|
189
|
+
address: string;
|
|
190
|
+
includeComponents?: boolean;
|
|
191
|
+
}): Promise<AddressNormalizerResult>;
|
|
192
|
+
/** Generate a color palette from a description or hex color */
|
|
193
|
+
colorPalette(input: {
|
|
194
|
+
description: string;
|
|
195
|
+
count?: number;
|
|
196
|
+
format?: "hex" | "rgb" | "hsl" | "all";
|
|
197
|
+
includeShades?: boolean;
|
|
198
|
+
}): Promise<ColorPaletteResult>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { type AddressNormalizerResult, AgentToolbelt, type AgentToolbeltOptions, type ColorPaletteResult, type CronBuilderResult, type CsvToJsonResult, type MarkdownConverterResult, type RegexBuilderResult, type SchemaGeneratorResult, type TextExtractorResult, type TokenCountResult, type UrlMetadataResult };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
interface AgentToolbeltOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
interface SchemaGeneratorResult {
|
|
6
|
+
schema: object | string;
|
|
7
|
+
format: "json_schema" | "zod" | "typescript";
|
|
8
|
+
}
|
|
9
|
+
interface TextExtractorResult {
|
|
10
|
+
extracted: Record<string, string[]>;
|
|
11
|
+
summary: {
|
|
12
|
+
totalItemsFound: number;
|
|
13
|
+
byType: Record<string, number>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
interface TokenCountResult {
|
|
17
|
+
characterCount: number;
|
|
18
|
+
wordCount: number;
|
|
19
|
+
results: Record<string, {
|
|
20
|
+
tokens: number;
|
|
21
|
+
encoding: string;
|
|
22
|
+
approximate: boolean;
|
|
23
|
+
estimatedCost?: {
|
|
24
|
+
input: number;
|
|
25
|
+
output: number;
|
|
26
|
+
currency: string;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
supportedModels: string[];
|
|
30
|
+
}
|
|
31
|
+
interface CsvToJsonResult {
|
|
32
|
+
success: boolean;
|
|
33
|
+
rows: Record<string, unknown>[];
|
|
34
|
+
headers: string[];
|
|
35
|
+
rowCount: number;
|
|
36
|
+
totalRows: number;
|
|
37
|
+
columnCount: number;
|
|
38
|
+
columnTypes: Record<string, string>;
|
|
39
|
+
detectedDelimiter?: string;
|
|
40
|
+
truncated?: boolean;
|
|
41
|
+
}
|
|
42
|
+
interface MarkdownConverterResult {
|
|
43
|
+
output: string;
|
|
44
|
+
from: string;
|
|
45
|
+
to: string;
|
|
46
|
+
inputLength: number;
|
|
47
|
+
outputLength: number;
|
|
48
|
+
}
|
|
49
|
+
interface UrlMetadataResult {
|
|
50
|
+
url: string;
|
|
51
|
+
finalUrl: string;
|
|
52
|
+
statusCode: number | null;
|
|
53
|
+
error?: string;
|
|
54
|
+
metadata: {
|
|
55
|
+
title: string | null;
|
|
56
|
+
description: string | null;
|
|
57
|
+
favicon: string | null;
|
|
58
|
+
canonical: string | null;
|
|
59
|
+
author: string | null;
|
|
60
|
+
themeColor: string | null;
|
|
61
|
+
publishedTime: string | null;
|
|
62
|
+
modifiedTime: string | null;
|
|
63
|
+
og: Record<string, string>;
|
|
64
|
+
twitter: Record<string, string>;
|
|
65
|
+
} | null;
|
|
66
|
+
}
|
|
67
|
+
interface RegexBuilderResult {
|
|
68
|
+
pattern: string;
|
|
69
|
+
flags: string;
|
|
70
|
+
regexLiteral: string;
|
|
71
|
+
description: string;
|
|
72
|
+
category: string;
|
|
73
|
+
codeSnippets: {
|
|
74
|
+
javascript: string;
|
|
75
|
+
python: string;
|
|
76
|
+
typescript: string;
|
|
77
|
+
};
|
|
78
|
+
testResults?: Array<{
|
|
79
|
+
input: string;
|
|
80
|
+
matched: boolean;
|
|
81
|
+
matches: string[];
|
|
82
|
+
}>;
|
|
83
|
+
}
|
|
84
|
+
interface CronBuilderResult {
|
|
85
|
+
expression: string;
|
|
86
|
+
humanReadable: string;
|
|
87
|
+
timezone: string;
|
|
88
|
+
fields: Record<string, string>;
|
|
89
|
+
nextRuns: string[];
|
|
90
|
+
warnings: string[];
|
|
91
|
+
}
|
|
92
|
+
interface AddressNormalizerResult {
|
|
93
|
+
original: string;
|
|
94
|
+
normalized: string;
|
|
95
|
+
confidence: "high" | "medium" | "low";
|
|
96
|
+
components?: {
|
|
97
|
+
streetNumber?: string;
|
|
98
|
+
preDirectional?: string;
|
|
99
|
+
streetName?: string;
|
|
100
|
+
streetType?: string;
|
|
101
|
+
postDirectional?: string;
|
|
102
|
+
secondaryUnit?: string;
|
|
103
|
+
secondaryNumber?: string;
|
|
104
|
+
city?: string;
|
|
105
|
+
state?: string;
|
|
106
|
+
zip?: string;
|
|
107
|
+
zip4?: string;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
interface ColorPaletteResult {
|
|
111
|
+
paletteName: string;
|
|
112
|
+
paletteLabel: string;
|
|
113
|
+
colors: Array<{
|
|
114
|
+
index: number;
|
|
115
|
+
name: string;
|
|
116
|
+
hex: string;
|
|
117
|
+
rgb?: string;
|
|
118
|
+
hsl?: string;
|
|
119
|
+
wcag: {
|
|
120
|
+
contrastOnWhite: number;
|
|
121
|
+
contrastOnBlack: number;
|
|
122
|
+
gradeOnWhite: string;
|
|
123
|
+
gradeOnBlack: string;
|
|
124
|
+
};
|
|
125
|
+
}>;
|
|
126
|
+
css: string;
|
|
127
|
+
swatches: string;
|
|
128
|
+
}
|
|
129
|
+
declare class AgentToolbelt {
|
|
130
|
+
private apiKey;
|
|
131
|
+
private baseUrl;
|
|
132
|
+
constructor({ apiKey, baseUrl }: AgentToolbeltOptions);
|
|
133
|
+
private call;
|
|
134
|
+
/** Generate JSON Schema, TypeScript, or Zod from a plain-English description */
|
|
135
|
+
schemaGenerator(input: {
|
|
136
|
+
description: string;
|
|
137
|
+
format?: "json_schema" | "zod" | "typescript";
|
|
138
|
+
strict?: boolean;
|
|
139
|
+
}): Promise<SchemaGeneratorResult>;
|
|
140
|
+
/** Extract emails, URLs, phone numbers, dates, currencies, addresses, or names from text */
|
|
141
|
+
textExtractor(input: {
|
|
142
|
+
text: string;
|
|
143
|
+
extractors: Array<"emails" | "urls" | "phone_numbers" | "dates" | "currencies" | "addresses" | "names" | "json_blocks">;
|
|
144
|
+
deduplicate?: boolean;
|
|
145
|
+
}): Promise<TextExtractorResult>;
|
|
146
|
+
/** Count tokens across multiple LLM models with cost estimates */
|
|
147
|
+
tokenCounter(input: {
|
|
148
|
+
text: string;
|
|
149
|
+
models?: string[];
|
|
150
|
+
}): Promise<TokenCountResult>;
|
|
151
|
+
/** Convert CSV to typed JSON with auto-delimiter detection and type casting */
|
|
152
|
+
csvToJson(input: {
|
|
153
|
+
csv: string;
|
|
154
|
+
delimiter?: "auto" | "," | ";" | "\t" | "|";
|
|
155
|
+
hasHeader?: boolean;
|
|
156
|
+
typeCast?: boolean;
|
|
157
|
+
limit?: number;
|
|
158
|
+
skipEmptyRows?: boolean;
|
|
159
|
+
}): Promise<CsvToJsonResult>;
|
|
160
|
+
/** Convert HTML to Markdown or Markdown to HTML */
|
|
161
|
+
markdownConverter(input: {
|
|
162
|
+
content: string;
|
|
163
|
+
from: "html" | "markdown";
|
|
164
|
+
to: "html" | "markdown";
|
|
165
|
+
options?: {
|
|
166
|
+
headingStyle?: "atx" | "setext";
|
|
167
|
+
bulletListMarker?: "-" | "*" | "+";
|
|
168
|
+
codeBlockStyle?: "fenced" | "indented";
|
|
169
|
+
};
|
|
170
|
+
}): Promise<MarkdownConverterResult>;
|
|
171
|
+
/** Fetch a URL and extract title, description, OG tags, favicon, and more */
|
|
172
|
+
urlMetadata(input: {
|
|
173
|
+
url: string;
|
|
174
|
+
timeout?: number;
|
|
175
|
+
}): Promise<UrlMetadataResult>;
|
|
176
|
+
/** Build and test regular expressions from natural language */
|
|
177
|
+
regexBuilder(input: {
|
|
178
|
+
description: string;
|
|
179
|
+
testStrings?: string[];
|
|
180
|
+
flags?: string;
|
|
181
|
+
}): Promise<RegexBuilderResult>;
|
|
182
|
+
/** Convert a natural language schedule to a cron expression */
|
|
183
|
+
cronBuilder(input: {
|
|
184
|
+
description: string;
|
|
185
|
+
timezone?: string;
|
|
186
|
+
}): Promise<CronBuilderResult>;
|
|
187
|
+
/** Normalize a US address to USPS format with component parsing */
|
|
188
|
+
addressNormalizer(input: {
|
|
189
|
+
address: string;
|
|
190
|
+
includeComponents?: boolean;
|
|
191
|
+
}): Promise<AddressNormalizerResult>;
|
|
192
|
+
/** Generate a color palette from a description or hex color */
|
|
193
|
+
colorPalette(input: {
|
|
194
|
+
description: string;
|
|
195
|
+
count?: number;
|
|
196
|
+
format?: "hex" | "rgb" | "hsl" | "all";
|
|
197
|
+
includeShades?: boolean;
|
|
198
|
+
}): Promise<ColorPaletteResult>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { type AddressNormalizerResult, AgentToolbelt, type AgentToolbeltOptions, type ColorPaletteResult, type CronBuilderResult, type CsvToJsonResult, type MarkdownConverterResult, type RegexBuilderResult, type SchemaGeneratorResult, type TextExtractorResult, type TokenCountResult, type UrlMetadataResult };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AgentToolbelt: () => AgentToolbelt
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/client.ts
|
|
28
|
+
var DEFAULT_BASE_URL = "https://agent-toolbelt-production.up.railway.app";
|
|
29
|
+
var AgentToolbelt = class {
|
|
30
|
+
constructor({ apiKey, baseUrl = DEFAULT_BASE_URL }) {
|
|
31
|
+
if (!apiKey) throw new Error("AgentToolbelt: apiKey is required");
|
|
32
|
+
this.apiKey = apiKey;
|
|
33
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
34
|
+
}
|
|
35
|
+
async call(tool, input) {
|
|
36
|
+
const res = await fetch(`${this.baseUrl}/api/tools/${tool}`, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers: {
|
|
39
|
+
"Content-Type": "application/json",
|
|
40
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
41
|
+
},
|
|
42
|
+
body: JSON.stringify(input)
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const err = await res.json().catch(() => ({}));
|
|
46
|
+
throw new Error(
|
|
47
|
+
`AgentToolbelt API error (${res.status}): ${err.message || err.error || res.statusText}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const data = await res.json();
|
|
51
|
+
return data.result;
|
|
52
|
+
}
|
|
53
|
+
/** Generate JSON Schema, TypeScript, or Zod from a plain-English description */
|
|
54
|
+
schemaGenerator(input) {
|
|
55
|
+
return this.call("schema-generator", input);
|
|
56
|
+
}
|
|
57
|
+
/** Extract emails, URLs, phone numbers, dates, currencies, addresses, or names from text */
|
|
58
|
+
textExtractor(input) {
|
|
59
|
+
return this.call("text-extractor", input);
|
|
60
|
+
}
|
|
61
|
+
/** Count tokens across multiple LLM models with cost estimates */
|
|
62
|
+
tokenCounter(input) {
|
|
63
|
+
return this.call("token-counter", input);
|
|
64
|
+
}
|
|
65
|
+
/** Convert CSV to typed JSON with auto-delimiter detection and type casting */
|
|
66
|
+
csvToJson(input) {
|
|
67
|
+
return this.call("csv-to-json", input);
|
|
68
|
+
}
|
|
69
|
+
/** Convert HTML to Markdown or Markdown to HTML */
|
|
70
|
+
markdownConverter(input) {
|
|
71
|
+
return this.call("markdown-converter", input);
|
|
72
|
+
}
|
|
73
|
+
/** Fetch a URL and extract title, description, OG tags, favicon, and more */
|
|
74
|
+
urlMetadata(input) {
|
|
75
|
+
return this.call("url-metadata", input);
|
|
76
|
+
}
|
|
77
|
+
/** Build and test regular expressions from natural language */
|
|
78
|
+
regexBuilder(input) {
|
|
79
|
+
return this.call("regex-builder", input);
|
|
80
|
+
}
|
|
81
|
+
/** Convert a natural language schedule to a cron expression */
|
|
82
|
+
cronBuilder(input) {
|
|
83
|
+
return this.call("cron-builder", input);
|
|
84
|
+
}
|
|
85
|
+
/** Normalize a US address to USPS format with component parsing */
|
|
86
|
+
addressNormalizer(input) {
|
|
87
|
+
return this.call("address-normalizer", input);
|
|
88
|
+
}
|
|
89
|
+
/** Generate a color palette from a description or hex color */
|
|
90
|
+
colorPalette(input) {
|
|
91
|
+
return this.call("color-palette", input);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
95
|
+
0 && (module.exports = {
|
|
96
|
+
AgentToolbelt
|
|
97
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
var DEFAULT_BASE_URL = "https://agent-toolbelt-production.up.railway.app";
|
|
3
|
+
var AgentToolbelt = class {
|
|
4
|
+
constructor({ apiKey, baseUrl = DEFAULT_BASE_URL }) {
|
|
5
|
+
if (!apiKey) throw new Error("AgentToolbelt: apiKey is required");
|
|
6
|
+
this.apiKey = apiKey;
|
|
7
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
8
|
+
}
|
|
9
|
+
async call(tool, input) {
|
|
10
|
+
const res = await fetch(`${this.baseUrl}/api/tools/${tool}`, {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: {
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
15
|
+
},
|
|
16
|
+
body: JSON.stringify(input)
|
|
17
|
+
});
|
|
18
|
+
if (!res.ok) {
|
|
19
|
+
const err = await res.json().catch(() => ({}));
|
|
20
|
+
throw new Error(
|
|
21
|
+
`AgentToolbelt API error (${res.status}): ${err.message || err.error || res.statusText}`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
const data = await res.json();
|
|
25
|
+
return data.result;
|
|
26
|
+
}
|
|
27
|
+
/** Generate JSON Schema, TypeScript, or Zod from a plain-English description */
|
|
28
|
+
schemaGenerator(input) {
|
|
29
|
+
return this.call("schema-generator", input);
|
|
30
|
+
}
|
|
31
|
+
/** Extract emails, URLs, phone numbers, dates, currencies, addresses, or names from text */
|
|
32
|
+
textExtractor(input) {
|
|
33
|
+
return this.call("text-extractor", input);
|
|
34
|
+
}
|
|
35
|
+
/** Count tokens across multiple LLM models with cost estimates */
|
|
36
|
+
tokenCounter(input) {
|
|
37
|
+
return this.call("token-counter", input);
|
|
38
|
+
}
|
|
39
|
+
/** Convert CSV to typed JSON with auto-delimiter detection and type casting */
|
|
40
|
+
csvToJson(input) {
|
|
41
|
+
return this.call("csv-to-json", input);
|
|
42
|
+
}
|
|
43
|
+
/** Convert HTML to Markdown or Markdown to HTML */
|
|
44
|
+
markdownConverter(input) {
|
|
45
|
+
return this.call("markdown-converter", input);
|
|
46
|
+
}
|
|
47
|
+
/** Fetch a URL and extract title, description, OG tags, favicon, and more */
|
|
48
|
+
urlMetadata(input) {
|
|
49
|
+
return this.call("url-metadata", input);
|
|
50
|
+
}
|
|
51
|
+
/** Build and test regular expressions from natural language */
|
|
52
|
+
regexBuilder(input) {
|
|
53
|
+
return this.call("regex-builder", input);
|
|
54
|
+
}
|
|
55
|
+
/** Convert a natural language schedule to a cron expression */
|
|
56
|
+
cronBuilder(input) {
|
|
57
|
+
return this.call("cron-builder", input);
|
|
58
|
+
}
|
|
59
|
+
/** Normalize a US address to USPS format with component parsing */
|
|
60
|
+
addressNormalizer(input) {
|
|
61
|
+
return this.call("address-normalizer", input);
|
|
62
|
+
}
|
|
63
|
+
/** Generate a color palette from a description or hex color */
|
|
64
|
+
colorPalette(input) {
|
|
65
|
+
return this.call("color-palette", input);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export {
|
|
69
|
+
AgentToolbelt
|
|
70
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
2
|
+
import { AgentToolbelt } from './index.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create a set of LangChain DynamicStructuredTools from an AgentToolbelt client.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { AgentToolbelt } from "agent-toolbelt";
|
|
10
|
+
* import { createLangChainTools } from "agent-toolbelt/langchain";
|
|
11
|
+
* import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
12
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
13
|
+
*
|
|
14
|
+
* const client = new AgentToolbelt({ apiKey: process.env.AGENT_TOOLBELT_KEY! });
|
|
15
|
+
* const tools = createLangChainTools(client);
|
|
16
|
+
*
|
|
17
|
+
* const agent = createReactAgent({ llm: new ChatOpenAI({ model: "gpt-4o" }), tools });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createLangChainTools(client: AgentToolbelt): DynamicStructuredTool[];
|
|
21
|
+
|
|
22
|
+
export { createLangChainTools };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
2
|
+
import { AgentToolbelt } from './index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create a set of LangChain DynamicStructuredTools from an AgentToolbelt client.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { AgentToolbelt } from "agent-toolbelt";
|
|
10
|
+
* import { createLangChainTools } from "agent-toolbelt/langchain";
|
|
11
|
+
* import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
12
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
13
|
+
*
|
|
14
|
+
* const client = new AgentToolbelt({ apiKey: process.env.AGENT_TOOLBELT_KEY! });
|
|
15
|
+
* const tools = createLangChainTools(client);
|
|
16
|
+
*
|
|
17
|
+
* const agent = createReactAgent({ llm: new ChatOpenAI({ model: "gpt-4o" }), tools });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createLangChainTools(client: AgentToolbelt): DynamicStructuredTool[];
|
|
21
|
+
|
|
22
|
+
export { createLangChainTools };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/langchain.ts
|
|
21
|
+
var langchain_exports = {};
|
|
22
|
+
__export(langchain_exports, {
|
|
23
|
+
createLangChainTools: () => createLangChainTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(langchain_exports);
|
|
26
|
+
var import_tools = require("@langchain/core/tools");
|
|
27
|
+
var import_zod = require("zod");
|
|
28
|
+
function createLangChainTools(client) {
|
|
29
|
+
return [
|
|
30
|
+
// ---- Text Extractor ----
|
|
31
|
+
new import_tools.DynamicStructuredTool({
|
|
32
|
+
name: "extract_from_text",
|
|
33
|
+
description: "Extract structured data from raw, unstructured text. Use this when you need to pull out specific types of data from a document, email, web page, or any text \u2014 such as all email addresses, phone numbers, dates, URLs, currencies, addresses, or names. Returns a structured JSON object with arrays of matched items per type. Example use cases: parsing contact info from a scraped page, finding all dates in a contract, extracting prices from a product description.",
|
|
34
|
+
schema: import_zod.z.object({
|
|
35
|
+
text: import_zod.z.string().describe("The raw text to extract data from"),
|
|
36
|
+
extractors: import_zod.z.array(import_zod.z.enum(["emails", "urls", "phone_numbers", "dates", "currencies", "addresses", "names", "json_blocks"])).describe("Which types of data to extract. Pick all that apply."),
|
|
37
|
+
deduplicate: import_zod.z.boolean().default(true).describe("Remove duplicate results")
|
|
38
|
+
}),
|
|
39
|
+
func: async ({ text, extractors, deduplicate }) => {
|
|
40
|
+
const result = await client.textExtractor({ text, extractors, deduplicate });
|
|
41
|
+
return JSON.stringify(result);
|
|
42
|
+
}
|
|
43
|
+
}),
|
|
44
|
+
// ---- Token Counter ----
|
|
45
|
+
new import_tools.DynamicStructuredTool({
|
|
46
|
+
name: "count_tokens",
|
|
47
|
+
description: "Count how many tokens a piece of text will consume in different LLM models, and estimate the API cost. Use this before sending large text to an LLM to check if it fits in the context window, to compare costs across models, or to decide whether to chunk or summarize content. Supports GPT-4o, GPT-4, GPT-3.5-turbo, Claude 3.5 Sonnet, Claude 3 Opus, and 10+ other models. Returns exact token counts for OpenAI models and close approximations for Claude.",
|
|
48
|
+
schema: import_zod.z.object({
|
|
49
|
+
text: import_zod.z.string().describe("The text to count tokens for"),
|
|
50
|
+
models: import_zod.z.array(import_zod.z.string()).default(["gpt-4o", "claude-3-5-sonnet"]).describe("Models to count tokens for. Defaults to gpt-4o and claude-3-5-sonnet.")
|
|
51
|
+
}),
|
|
52
|
+
func: async ({ text, models }) => {
|
|
53
|
+
const result = await client.tokenCounter({ text, models });
|
|
54
|
+
return JSON.stringify(result);
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
// ---- Schema Generator ----
|
|
58
|
+
new import_tools.DynamicStructuredTool({
|
|
59
|
+
name: "generate_schema",
|
|
60
|
+
description: "Generate a JSON Schema, TypeScript interface, or Zod validation schema from a plain English description of a data structure. Use this when you need to define a data model, validate incoming data, or create type definitions without writing them by hand. Example: 'a user profile with name, email, and subscription tier' \u2192 full JSON Schema with required fields and types. Ideal for agents that dynamically create or validate data structures based on user requirements.",
|
|
61
|
+
schema: import_zod.z.object({
|
|
62
|
+
description: import_zod.z.string().describe("Plain English description of the data structure. Be specific about field names and types."),
|
|
63
|
+
format: import_zod.z.enum(["json_schema", "typescript", "zod"]).default("json_schema").describe("Output format: json_schema (standard), typescript (TS interface), or zod (Zod validator)"),
|
|
64
|
+
strict: import_zod.z.boolean().default(true).describe("If true, all fields are required")
|
|
65
|
+
}),
|
|
66
|
+
func: async ({ description, format, strict }) => {
|
|
67
|
+
const result = await client.schemaGenerator({ description, format, strict });
|
|
68
|
+
return typeof result.schema === "string" ? result.schema : JSON.stringify(result.schema, null, 2);
|
|
69
|
+
}
|
|
70
|
+
}),
|
|
71
|
+
// ---- CSV to JSON ----
|
|
72
|
+
new import_tools.DynamicStructuredTool({
|
|
73
|
+
name: "csv_to_json",
|
|
74
|
+
description: "Convert CSV data into typed JSON. Use this when you have spreadsheet data, database exports, or any CSV-formatted content that needs to be processed as structured JSON. Automatically detects delimiters (comma, tab, semicolon, pipe), converts numbers to actual numbers, 'true'/'false' to booleans, empty cells to null, and infers column types. Returns an array of row objects with column names as keys.",
|
|
75
|
+
schema: import_zod.z.object({
|
|
76
|
+
csv: import_zod.z.string().describe("The CSV content to convert"),
|
|
77
|
+
delimiter: import_zod.z.enum(["auto", ",", ";", " ", "|"]).default("auto").describe("Column delimiter (auto-detects by default)"),
|
|
78
|
+
hasHeader: import_zod.z.boolean().default(true).describe("Whether the first row contains column names"),
|
|
79
|
+
typeCast: import_zod.z.boolean().default(true).describe("Auto-convert values to numbers, booleans, and nulls"),
|
|
80
|
+
limit: import_zod.z.number().optional().describe("Max rows to return (useful for large files)")
|
|
81
|
+
}),
|
|
82
|
+
func: async ({ csv, delimiter, hasHeader, typeCast, limit }) => {
|
|
83
|
+
const result = await client.csvToJson({ csv, delimiter, hasHeader, typeCast, limit, skipEmptyRows: true });
|
|
84
|
+
return JSON.stringify(result);
|
|
85
|
+
}
|
|
86
|
+
}),
|
|
87
|
+
// ---- Markdown Converter ----
|
|
88
|
+
new import_tools.DynamicStructuredTool({
|
|
89
|
+
name: "convert_markdown",
|
|
90
|
+
description: "Convert HTML to clean Markdown, or Markdown to HTML. Use HTML\u2192Markdown when you've fetched a web page and need clean, readable text for an LLM \u2014 stripping HTML tags, preserving structure (headings, lists, code blocks, links, tables). Use Markdown\u2192HTML when you need to render content in a web context. Handles complex HTML including nested lists, code blocks with language hints, tables, and inline formatting.",
|
|
91
|
+
schema: import_zod.z.object({
|
|
92
|
+
content: import_zod.z.string().describe("The content to convert"),
|
|
93
|
+
from: import_zod.z.enum(["html", "markdown"]).describe("Input format"),
|
|
94
|
+
to: import_zod.z.enum(["html", "markdown"]).describe("Output format")
|
|
95
|
+
}),
|
|
96
|
+
func: async ({ content, from, to }) => {
|
|
97
|
+
const result = await client.markdownConverter({ content, from, to });
|
|
98
|
+
return result.output;
|
|
99
|
+
}
|
|
100
|
+
}),
|
|
101
|
+
// ---- URL Metadata ----
|
|
102
|
+
new import_tools.DynamicStructuredTool({
|
|
103
|
+
name: "fetch_url_metadata",
|
|
104
|
+
description: "Fetch a URL and extract its metadata: page title, meta description, Open Graph tags (og:image, og:type, og:site_name), Twitter card tags, favicon URL, canonical URL, author, and publish/modified dates. Use this to enrich a URL with context before presenting it to a user, to get the main image or description for a link preview, or to quickly understand what a page is about without reading the full content.",
|
|
105
|
+
schema: import_zod.z.object({
|
|
106
|
+
url: import_zod.z.string().url().describe("The URL to fetch metadata from"),
|
|
107
|
+
timeout: import_zod.z.number().default(8e3).describe("Request timeout in ms (default 8000)")
|
|
108
|
+
}),
|
|
109
|
+
func: async ({ url, timeout }) => {
|
|
110
|
+
const result = await client.urlMetadata({ url, timeout });
|
|
111
|
+
return JSON.stringify(result);
|
|
112
|
+
}
|
|
113
|
+
}),
|
|
114
|
+
// ---- Regex Builder ----
|
|
115
|
+
new import_tools.DynamicStructuredTool({
|
|
116
|
+
name: "build_regex",
|
|
117
|
+
description: "Build and test a regular expression from a natural language description. Use this when you need a regex pattern for validation, parsing, or data extraction \u2014 without needing to write or debug regex syntax yourself. Supports 20+ common patterns: email, URL, phone number, date, IP address, hex color, UUID, slug, JWT, credit card, SSN, and more. Optionally test the pattern against provided strings. Returns ready-to-use code in JavaScript, Python, and TypeScript.",
|
|
118
|
+
schema: import_zod.z.object({
|
|
119
|
+
description: import_zod.z.string().describe("What the regex should match (e.g. 'valid email addresses', 'US phone numbers with area code')"),
|
|
120
|
+
testStrings: import_zod.z.array(import_zod.z.string()).optional().describe("Optional strings to test the regex against"),
|
|
121
|
+
flags: import_zod.z.string().default("g").describe("Regex flags (default: 'g' for global)")
|
|
122
|
+
}),
|
|
123
|
+
func: async ({ description, testStrings, flags }) => {
|
|
124
|
+
const result = await client.regexBuilder({ description, testStrings, flags });
|
|
125
|
+
return JSON.stringify(result);
|
|
126
|
+
}
|
|
127
|
+
}),
|
|
128
|
+
// ---- Cron Builder ----
|
|
129
|
+
new import_tools.DynamicStructuredTool({
|
|
130
|
+
name: "build_cron",
|
|
131
|
+
description: "Convert a natural language schedule description into a cron expression. Use this when setting up scheduled jobs, tasks, or automation workflows. Examples: 'every weekday at 9am EST', 'first Monday of every month at noon', 'every 15 minutes', 'twice a day at 8am and 6pm'. Returns the cron expression, a human-readable confirmation of the schedule, and the next 5 run times.",
|
|
132
|
+
schema: import_zod.z.object({
|
|
133
|
+
description: import_zod.z.string().describe("Natural language schedule description"),
|
|
134
|
+
timezone: import_zod.z.string().default("UTC").describe("Timezone (e.g. 'America/New_York', 'Europe/London')")
|
|
135
|
+
}),
|
|
136
|
+
func: async ({ description, timezone }) => {
|
|
137
|
+
const result = await client.cronBuilder({ description, timezone });
|
|
138
|
+
return JSON.stringify(result);
|
|
139
|
+
}
|
|
140
|
+
}),
|
|
141
|
+
// ---- Address Normalizer ----
|
|
142
|
+
new import_tools.DynamicStructuredTool({
|
|
143
|
+
name: "normalize_address",
|
|
144
|
+
description: "Normalize a US mailing address to USPS standard format. Use this when cleaning address data for mailing, geocoding, deduplication, or database storage. Expands abbreviations (st\u2192ST, ave\u2192AVE, apt\u2192APT), standardizes directionals (north\u2192N), converts state names to abbreviations (California\u2192CA), and parses the address into components. Returns a confidence score (high/medium/low) indicating parse quality.",
|
|
145
|
+
schema: import_zod.z.object({
|
|
146
|
+
address: import_zod.z.string().describe("The address to normalize (e.g. '123 main st apt 4b, springfield, il 62701')"),
|
|
147
|
+
includeComponents: import_zod.z.boolean().default(true).describe("Include parsed components (street number, city, state, ZIP, etc.)")
|
|
148
|
+
}),
|
|
149
|
+
func: async ({ address, includeComponents }) => {
|
|
150
|
+
const result = await client.addressNormalizer({ address, includeComponents });
|
|
151
|
+
return JSON.stringify(result);
|
|
152
|
+
}
|
|
153
|
+
}),
|
|
154
|
+
// ---- Color Palette ----
|
|
155
|
+
new import_tools.DynamicStructuredTool({
|
|
156
|
+
name: "generate_color_palette",
|
|
157
|
+
description: "Generate a color palette from a description, mood, industry, or hex color seed. Use this for branding, UI design, or any task requiring a cohesive set of colors. Accepts moods ('calm', 'energetic', 'luxurious'), industries ('fintech', 'healthcare', 'fashion'), nature themes ('sunset', 'ocean', 'forest'), or a specific hex color to build around. Returns hex/RGB/HSL values, WCAG accessibility contrast scores, and ready-to-use CSS custom properties.",
|
|
158
|
+
schema: import_zod.z.object({
|
|
159
|
+
description: import_zod.z.string().describe("Description of desired palette (e.g. 'professional fintech blue', 'warm sunset', '#3B82F6')"),
|
|
160
|
+
count: import_zod.z.number().int().min(2).max(10).default(5).describe("Number of colors (2-10)"),
|
|
161
|
+
format: import_zod.z.enum(["hex", "rgb", "hsl", "all"]).default("all").describe("Color format in output")
|
|
162
|
+
}),
|
|
163
|
+
func: async ({ description, count, format }) => {
|
|
164
|
+
const result = await client.colorPalette({ description, count, format });
|
|
165
|
+
return JSON.stringify(result);
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
171
|
+
0 && (module.exports = {
|
|
172
|
+
createLangChainTools
|
|
173
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// src/langchain.ts
|
|
2
|
+
import { DynamicStructuredTool } from "@langchain/core/tools";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
function createLangChainTools(client) {
|
|
5
|
+
return [
|
|
6
|
+
// ---- Text Extractor ----
|
|
7
|
+
new DynamicStructuredTool({
|
|
8
|
+
name: "extract_from_text",
|
|
9
|
+
description: "Extract structured data from raw, unstructured text. Use this when you need to pull out specific types of data from a document, email, web page, or any text \u2014 such as all email addresses, phone numbers, dates, URLs, currencies, addresses, or names. Returns a structured JSON object with arrays of matched items per type. Example use cases: parsing contact info from a scraped page, finding all dates in a contract, extracting prices from a product description.",
|
|
10
|
+
schema: z.object({
|
|
11
|
+
text: z.string().describe("The raw text to extract data from"),
|
|
12
|
+
extractors: z.array(z.enum(["emails", "urls", "phone_numbers", "dates", "currencies", "addresses", "names", "json_blocks"])).describe("Which types of data to extract. Pick all that apply."),
|
|
13
|
+
deduplicate: z.boolean().default(true).describe("Remove duplicate results")
|
|
14
|
+
}),
|
|
15
|
+
func: async ({ text, extractors, deduplicate }) => {
|
|
16
|
+
const result = await client.textExtractor({ text, extractors, deduplicate });
|
|
17
|
+
return JSON.stringify(result);
|
|
18
|
+
}
|
|
19
|
+
}),
|
|
20
|
+
// ---- Token Counter ----
|
|
21
|
+
new DynamicStructuredTool({
|
|
22
|
+
name: "count_tokens",
|
|
23
|
+
description: "Count how many tokens a piece of text will consume in different LLM models, and estimate the API cost. Use this before sending large text to an LLM to check if it fits in the context window, to compare costs across models, or to decide whether to chunk or summarize content. Supports GPT-4o, GPT-4, GPT-3.5-turbo, Claude 3.5 Sonnet, Claude 3 Opus, and 10+ other models. Returns exact token counts for OpenAI models and close approximations for Claude.",
|
|
24
|
+
schema: z.object({
|
|
25
|
+
text: z.string().describe("The text to count tokens for"),
|
|
26
|
+
models: z.array(z.string()).default(["gpt-4o", "claude-3-5-sonnet"]).describe("Models to count tokens for. Defaults to gpt-4o and claude-3-5-sonnet.")
|
|
27
|
+
}),
|
|
28
|
+
func: async ({ text, models }) => {
|
|
29
|
+
const result = await client.tokenCounter({ text, models });
|
|
30
|
+
return JSON.stringify(result);
|
|
31
|
+
}
|
|
32
|
+
}),
|
|
33
|
+
// ---- Schema Generator ----
|
|
34
|
+
new DynamicStructuredTool({
|
|
35
|
+
name: "generate_schema",
|
|
36
|
+
description: "Generate a JSON Schema, TypeScript interface, or Zod validation schema from a plain English description of a data structure. Use this when you need to define a data model, validate incoming data, or create type definitions without writing them by hand. Example: 'a user profile with name, email, and subscription tier' \u2192 full JSON Schema with required fields and types. Ideal for agents that dynamically create or validate data structures based on user requirements.",
|
|
37
|
+
schema: z.object({
|
|
38
|
+
description: z.string().describe("Plain English description of the data structure. Be specific about field names and types."),
|
|
39
|
+
format: z.enum(["json_schema", "typescript", "zod"]).default("json_schema").describe("Output format: json_schema (standard), typescript (TS interface), or zod (Zod validator)"),
|
|
40
|
+
strict: z.boolean().default(true).describe("If true, all fields are required")
|
|
41
|
+
}),
|
|
42
|
+
func: async ({ description, format, strict }) => {
|
|
43
|
+
const result = await client.schemaGenerator({ description, format, strict });
|
|
44
|
+
return typeof result.schema === "string" ? result.schema : JSON.stringify(result.schema, null, 2);
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
// ---- CSV to JSON ----
|
|
48
|
+
new DynamicStructuredTool({
|
|
49
|
+
name: "csv_to_json",
|
|
50
|
+
description: "Convert CSV data into typed JSON. Use this when you have spreadsheet data, database exports, or any CSV-formatted content that needs to be processed as structured JSON. Automatically detects delimiters (comma, tab, semicolon, pipe), converts numbers to actual numbers, 'true'/'false' to booleans, empty cells to null, and infers column types. Returns an array of row objects with column names as keys.",
|
|
51
|
+
schema: z.object({
|
|
52
|
+
csv: z.string().describe("The CSV content to convert"),
|
|
53
|
+
delimiter: z.enum(["auto", ",", ";", " ", "|"]).default("auto").describe("Column delimiter (auto-detects by default)"),
|
|
54
|
+
hasHeader: z.boolean().default(true).describe("Whether the first row contains column names"),
|
|
55
|
+
typeCast: z.boolean().default(true).describe("Auto-convert values to numbers, booleans, and nulls"),
|
|
56
|
+
limit: z.number().optional().describe("Max rows to return (useful for large files)")
|
|
57
|
+
}),
|
|
58
|
+
func: async ({ csv, delimiter, hasHeader, typeCast, limit }) => {
|
|
59
|
+
const result = await client.csvToJson({ csv, delimiter, hasHeader, typeCast, limit, skipEmptyRows: true });
|
|
60
|
+
return JSON.stringify(result);
|
|
61
|
+
}
|
|
62
|
+
}),
|
|
63
|
+
// ---- Markdown Converter ----
|
|
64
|
+
new DynamicStructuredTool({
|
|
65
|
+
name: "convert_markdown",
|
|
66
|
+
description: "Convert HTML to clean Markdown, or Markdown to HTML. Use HTML\u2192Markdown when you've fetched a web page and need clean, readable text for an LLM \u2014 stripping HTML tags, preserving structure (headings, lists, code blocks, links, tables). Use Markdown\u2192HTML when you need to render content in a web context. Handles complex HTML including nested lists, code blocks with language hints, tables, and inline formatting.",
|
|
67
|
+
schema: z.object({
|
|
68
|
+
content: z.string().describe("The content to convert"),
|
|
69
|
+
from: z.enum(["html", "markdown"]).describe("Input format"),
|
|
70
|
+
to: z.enum(["html", "markdown"]).describe("Output format")
|
|
71
|
+
}),
|
|
72
|
+
func: async ({ content, from, to }) => {
|
|
73
|
+
const result = await client.markdownConverter({ content, from, to });
|
|
74
|
+
return result.output;
|
|
75
|
+
}
|
|
76
|
+
}),
|
|
77
|
+
// ---- URL Metadata ----
|
|
78
|
+
new DynamicStructuredTool({
|
|
79
|
+
name: "fetch_url_metadata",
|
|
80
|
+
description: "Fetch a URL and extract its metadata: page title, meta description, Open Graph tags (og:image, og:type, og:site_name), Twitter card tags, favicon URL, canonical URL, author, and publish/modified dates. Use this to enrich a URL with context before presenting it to a user, to get the main image or description for a link preview, or to quickly understand what a page is about without reading the full content.",
|
|
81
|
+
schema: z.object({
|
|
82
|
+
url: z.string().url().describe("The URL to fetch metadata from"),
|
|
83
|
+
timeout: z.number().default(8e3).describe("Request timeout in ms (default 8000)")
|
|
84
|
+
}),
|
|
85
|
+
func: async ({ url, timeout }) => {
|
|
86
|
+
const result = await client.urlMetadata({ url, timeout });
|
|
87
|
+
return JSON.stringify(result);
|
|
88
|
+
}
|
|
89
|
+
}),
|
|
90
|
+
// ---- Regex Builder ----
|
|
91
|
+
new DynamicStructuredTool({
|
|
92
|
+
name: "build_regex",
|
|
93
|
+
description: "Build and test a regular expression from a natural language description. Use this when you need a regex pattern for validation, parsing, or data extraction \u2014 without needing to write or debug regex syntax yourself. Supports 20+ common patterns: email, URL, phone number, date, IP address, hex color, UUID, slug, JWT, credit card, SSN, and more. Optionally test the pattern against provided strings. Returns ready-to-use code in JavaScript, Python, and TypeScript.",
|
|
94
|
+
schema: z.object({
|
|
95
|
+
description: z.string().describe("What the regex should match (e.g. 'valid email addresses', 'US phone numbers with area code')"),
|
|
96
|
+
testStrings: z.array(z.string()).optional().describe("Optional strings to test the regex against"),
|
|
97
|
+
flags: z.string().default("g").describe("Regex flags (default: 'g' for global)")
|
|
98
|
+
}),
|
|
99
|
+
func: async ({ description, testStrings, flags }) => {
|
|
100
|
+
const result = await client.regexBuilder({ description, testStrings, flags });
|
|
101
|
+
return JSON.stringify(result);
|
|
102
|
+
}
|
|
103
|
+
}),
|
|
104
|
+
// ---- Cron Builder ----
|
|
105
|
+
new DynamicStructuredTool({
|
|
106
|
+
name: "build_cron",
|
|
107
|
+
description: "Convert a natural language schedule description into a cron expression. Use this when setting up scheduled jobs, tasks, or automation workflows. Examples: 'every weekday at 9am EST', 'first Monday of every month at noon', 'every 15 minutes', 'twice a day at 8am and 6pm'. Returns the cron expression, a human-readable confirmation of the schedule, and the next 5 run times.",
|
|
108
|
+
schema: z.object({
|
|
109
|
+
description: z.string().describe("Natural language schedule description"),
|
|
110
|
+
timezone: z.string().default("UTC").describe("Timezone (e.g. 'America/New_York', 'Europe/London')")
|
|
111
|
+
}),
|
|
112
|
+
func: async ({ description, timezone }) => {
|
|
113
|
+
const result = await client.cronBuilder({ description, timezone });
|
|
114
|
+
return JSON.stringify(result);
|
|
115
|
+
}
|
|
116
|
+
}),
|
|
117
|
+
// ---- Address Normalizer ----
|
|
118
|
+
new DynamicStructuredTool({
|
|
119
|
+
name: "normalize_address",
|
|
120
|
+
description: "Normalize a US mailing address to USPS standard format. Use this when cleaning address data for mailing, geocoding, deduplication, or database storage. Expands abbreviations (st\u2192ST, ave\u2192AVE, apt\u2192APT), standardizes directionals (north\u2192N), converts state names to abbreviations (California\u2192CA), and parses the address into components. Returns a confidence score (high/medium/low) indicating parse quality.",
|
|
121
|
+
schema: z.object({
|
|
122
|
+
address: z.string().describe("The address to normalize (e.g. '123 main st apt 4b, springfield, il 62701')"),
|
|
123
|
+
includeComponents: z.boolean().default(true).describe("Include parsed components (street number, city, state, ZIP, etc.)")
|
|
124
|
+
}),
|
|
125
|
+
func: async ({ address, includeComponents }) => {
|
|
126
|
+
const result = await client.addressNormalizer({ address, includeComponents });
|
|
127
|
+
return JSON.stringify(result);
|
|
128
|
+
}
|
|
129
|
+
}),
|
|
130
|
+
// ---- Color Palette ----
|
|
131
|
+
new DynamicStructuredTool({
|
|
132
|
+
name: "generate_color_palette",
|
|
133
|
+
description: "Generate a color palette from a description, mood, industry, or hex color seed. Use this for branding, UI design, or any task requiring a cohesive set of colors. Accepts moods ('calm', 'energetic', 'luxurious'), industries ('fintech', 'healthcare', 'fashion'), nature themes ('sunset', 'ocean', 'forest'), or a specific hex color to build around. Returns hex/RGB/HSL values, WCAG accessibility contrast scores, and ready-to-use CSS custom properties.",
|
|
134
|
+
schema: z.object({
|
|
135
|
+
description: z.string().describe("Description of desired palette (e.g. 'professional fintech blue', 'warm sunset', '#3B82F6')"),
|
|
136
|
+
count: z.number().int().min(2).max(10).default(5).describe("Number of colors (2-10)"),
|
|
137
|
+
format: z.enum(["hex", "rgb", "hsl", "all"]).default("all").describe("Color format in output")
|
|
138
|
+
}),
|
|
139
|
+
func: async ({ description, count, format }) => {
|
|
140
|
+
const result = await client.colorPalette({ description, count, format });
|
|
141
|
+
return JSON.stringify(result);
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
export {
|
|
147
|
+
createLangChainTools
|
|
148
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-toolbelt",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official SDK for Agent Toolbelt — typed API client and LangChain tool wrappers for schema generation, text extraction, token counting, CSV conversion, and more.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./langchain": {
|
|
15
|
+
"types": "./dist/langchain.d.ts",
|
|
16
|
+
"import": "./dist/langchain.mjs",
|
|
17
|
+
"require": "./dist/langchain.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": ["dist", "README.md"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup src/index.ts src/langchain.ts --format cjs,esm --dts",
|
|
23
|
+
"dev": "tsup src/index.ts src/langchain.ts --format cjs,esm --dts --watch"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"langchain", "ai", "agent", "tools", "schema", "text-extraction",
|
|
27
|
+
"token-counter", "csv", "markdown", "llm", "openai", "claude"
|
|
28
|
+
],
|
|
29
|
+
"author": "Agent Toolbelt",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/marras0914/agent-toolbelt"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://agent-toolbelt-production.up.railway.app",
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@langchain/core": ">=0.2.0",
|
|
38
|
+
"zod": ">=3.0.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"@langchain/core": { "optional": true }
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@langchain/core": "^0.3.0",
|
|
45
|
+
"@types/node": "^20.0.0",
|
|
46
|
+
"tsup": "^8.0.0",
|
|
47
|
+
"typescript": "^5.3.0",
|
|
48
|
+
"zod": "^3.22.0"
|
|
49
|
+
}
|
|
50
|
+
}
|