opentool 0.7.8 → 0.7.9
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 +53 -3
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +30 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +37 -4
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/{validate-BrOwtVYW.d.ts → validate-BBjyq5nS.d.ts} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
Build serverless TypeScript tools that work with AI assistants, handle crypto payments, and deploy to AWS Lambda automatically.
|
|
7
7
|
|
|
8
|
-
**For LLMs/AI Code Generation:** [`
|
|
8
|
+
**For LLMs/AI Code Generation:** [`context/opentool-context.ts`](./context/opentool-context.ts)
|
|
9
9
|
|
|
10
10
|
## What is it?
|
|
11
11
|
|
|
12
12
|
OpenTool lets you write simple TypeScript functions that can be called by other agents, monetized with crypto payments, and deployed as serverless functions. It handles the boring stuff like:
|
|
13
13
|
|
|
14
|
+
Tools are either Public or Private. Public tools are accessible to the public and are monetized with crypto payments using x402. Private tools are accessible only to the app developer and are mainly for trading and onchain interaction use cases.
|
|
15
|
+
|
|
14
16
|
## Installation
|
|
15
17
|
|
|
16
18
|
```bash
|
|
@@ -65,9 +67,57 @@ npx opentool validate
|
|
|
65
67
|
npx opentool dev
|
|
66
68
|
```
|
|
67
69
|
|
|
68
|
-
###
|
|
70
|
+
### Private tools: GET-only and POST-only
|
|
71
|
+
|
|
72
|
+
For private tools, say for internal trading apps:
|
|
73
|
+
|
|
74
|
+
- GET-only (scheduled default profile)
|
|
75
|
+
- POST-only (one-off, parameterized with Zod)
|
|
76
|
+
|
|
77
|
+
GET-only (scheduled default)
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// tools/aave-stake.ts
|
|
81
|
+
export const profile = {
|
|
82
|
+
description: "Stake 100 USDC daily at 12:00 UTC",
|
|
83
|
+
fixedAmount: "100",
|
|
84
|
+
tokenSymbol: "USDC",
|
|
85
|
+
schedule: { cron: "0 12 * * *", enabled: true },
|
|
86
|
+
limits: { concurrency: 1, dailyCap: 1 },
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export async function GET(_req: Request) {
|
|
90
|
+
const amount = profile.fixedAmount;
|
|
91
|
+
return Response.json({
|
|
92
|
+
ok: true,
|
|
93
|
+
action: "stake",
|
|
94
|
+
amount,
|
|
95
|
+
token: profile.tokenSymbol,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
POST-only (one-off)
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// tools/aave-unstake.ts
|
|
104
|
+
import { z } from "zod";
|
|
105
|
+
|
|
106
|
+
export const schema = z.object({
|
|
107
|
+
amount: z.string(),
|
|
108
|
+
token: z.string().default("USDC"),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export async function POST(req: Request) {
|
|
112
|
+
const body = await req.json();
|
|
113
|
+
const { amount, token } = schema.parse(body);
|
|
114
|
+
return Response.json({ ok: true, action: "unstake", amount, token });
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Public tools: Add x402 payments (optional)
|
|
69
119
|
|
|
70
|
-
Protect your tools with crypto payments using x402:
|
|
120
|
+
Protect your public tools with crypto payments using x402:
|
|
71
121
|
|
|
72
122
|
```typescript
|
|
73
123
|
// tools/premium-report.ts
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
export { G as GenerateMetadataOptions,
|
|
2
|
+
import { M as Metadata, I as InternalToolDefinition } from '../validate-BBjyq5nS.js';
|
|
3
|
+
export { G as GenerateMetadataOptions, a as GenerateMetadataResult, V as ValidateOptions, b as generateMetadata, g as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, c as validateFullCommand } from '../validate-BBjyq5nS.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import '../x402/index.js';
|
|
6
6
|
import 'viem';
|
package/dist/cli/index.js
CHANGED
|
@@ -1008,6 +1008,12 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1008
1008
|
if (fs4.existsSync(tempDir)) {
|
|
1009
1009
|
fs4.rmSync(tempDir, { recursive: true, force: true });
|
|
1010
1010
|
}
|
|
1011
|
+
const kebabCase = /^[a-z0-9]+(?:-[a-z0-9]+)*\.[a-z]+$/;
|
|
1012
|
+
for (const f of files) {
|
|
1013
|
+
if (!kebabCase.test(f)) {
|
|
1014
|
+
throw new Error(`Tool filename must be kebab-case: ${f}`);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1011
1017
|
const entryPoints = files.map((file) => path5.join(toolsDir, file));
|
|
1012
1018
|
const { outDir, cleanup } = await transpileWithEsbuild({
|
|
1013
1019
|
entryPoints,
|
|
@@ -1032,6 +1038,30 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1032
1038
|
const inputSchemaRaw = schema ? toJsonSchema(toolName, schema) : void 0;
|
|
1033
1039
|
const inputSchema = normalizeInputSchema(inputSchemaRaw);
|
|
1034
1040
|
const httpHandlersRaw = collectHttpHandlers(toolModule, file);
|
|
1041
|
+
const hasGET = typeof toolModule.GET === "function";
|
|
1042
|
+
const hasPOST = typeof toolModule.POST === "function";
|
|
1043
|
+
const otherMethods = HTTP_METHODS.filter((m) => m !== "GET" && m !== "POST").filter(
|
|
1044
|
+
(m) => typeof toolModule[m] === "function"
|
|
1045
|
+
);
|
|
1046
|
+
if (otherMethods.length > 0) {
|
|
1047
|
+
throw new Error(
|
|
1048
|
+
`${file} must not export ${otherMethods.join(", ")}. Only one of GET or POST is allowed.`
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
if (hasGET === hasPOST) {
|
|
1052
|
+
throw new Error(`${file}: export exactly one of GET or POST`);
|
|
1053
|
+
}
|
|
1054
|
+
if (hasGET) {
|
|
1055
|
+
const schedule = toolModule?.profile?.schedule;
|
|
1056
|
+
if (!schedule || typeof schedule?.cron !== "string" || schedule.cron.trim().length === 0) {
|
|
1057
|
+
throw new Error(`${file}: GET tools require profile.schedule { cron }`);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
if (hasPOST) {
|
|
1061
|
+
if (!schema) {
|
|
1062
|
+
throw new Error(`${file}: POST tools must export a Zod schema as 'schema'`);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1035
1065
|
const httpHandlers = [...httpHandlersRaw];
|
|
1036
1066
|
if (httpHandlers.length === 0) {
|
|
1037
1067
|
throw new Error(
|